我的程序与使用 2D 点(row,col)的计算机视觉库交互,并且它还与......假设世界其他地方使用点(x,y)。这些点包含相同的数据:row==y和col==x,唯一的区别是初始化的顺序。 我知道理想情况下我应该只选择一种初始化点的方法,即使用两种方法是通往地狱的大门,但由于我陷入这两种约定之间,并且 C++ 有时看起来像一棵具有神奇功能的圣诞树,所以我想知道是否有一个优雅的解决方案可以根据参数名称进行推断:
我想知道是否有一个优雅的解决方案可以根据参数名称进行推断
不,没有。正式参数的名称对任何事物都没有影响。特别是,这是一个合法的代码(不会因未来标准的更改而被破坏):
int foo(int a, int b); //declares int foo(int, int)
int foo(int c, int d); //declares int foo(int, int)
int foo(int x, int y){ //defines int foo(int, int)
//...
}
在您的情况下,一个好的解决方案是实现两种不同的类型:
struct CellCoord;
struct Point {
int x, y;
/* implicit */ Point(const CellCoord& c) : x(c.col), y(c.row) {}
};
struct CellCoord {
int row, col;
/* implicit */ CellCoord(const Point& p) : row(p.y), col(p.x) {}
};
有了这个,您可以根据一个结构编写每个类,并使用处理转换的构造函数传递另一个类:
//in part of the program working with points
void foo(Point p);
//in part of the program working with cells
void bar(CellCoord c);
Point p1, p2;
foo(p1); //normal call
bar(p2); //calls bar(CellCoord(p2))
如果您需要更好的类型安全性,您可以为不同的坐标引入特殊类型,而不是通用 int:
struct strong_typedef_int {
int val;
/* a bunch of overloaded operators */
};
struct Abscissa : public strong_typedef_int {};
struct Ordinate : public strong_typedef_int {};
struct Point {
Abscissa x;
Ordinate y;
// and so on
};
但是,这会让任何类型的旋转写起来都非常麻烦,这种技术最好保留给不同类型的ID之类的。
参数名称不是函数签名的一部分,因此编译器会触发该函数的重新定义错误。
void createPointRC(double row, double col);
void createPointXY(double x, double y);
struct PointRC
{
double row, col;
};
struct PointXY
{
double x, y;
};
void createPoint(const PointRC & point);
void createPoint(const PointXY & point);
namespace rc
{
void createPoint(double row, double col);
}
namespace xy
{
void createPoint(double x, double y);
}
您可以选择更适合您需求的解决方案