C++ 向类的构造函数添加伪参数以解决调用歧义是否违反任何规则?

C++ 向类的构造函数添加伪参数以解决调用歧义是否违反任何规则?,c++,constructor,initialization,ambiguity,named-constructor,C++,Constructor,Initialization,Ambiguity,Named Constructor,采用以下类和两个对象定义: class Rect{ public: enum centimeter; enum meter; Rect(double len,double wid,enum centimeter){ length=(len/100); width=(wid/100); } Rect(int len,int wid,enum meter){ length=len; width=wid; } //rest of implement

采用以下类和两个对象定义:

class Rect{
 public:
  enum centimeter;
  enum meter;
  Rect(double len,double wid,enum centimeter){
   length=(len/100);
   width=(wid/100);
  }
  Rect(int len,int wid,enum meter){
   length=len;
   width=wid;
  }
  //rest of implementation
 private:
  double length;//in meters
  double width;//in meters
};
Rect obj1(10,5,Rect::centimeter());
Rect obj2(10,5,Rect::meter());

前面的两个构造函数都有伪枚举参数,以解决在这些伪参数不存在的情况下导致的调用歧义。现在,尽管这里可能使用命名构造函数,但如果我坚持使用这些伪参数,这是否违反了我应该知道的任何编码规则?

我认为这违反了我的口味。我会这样编码:

enum Unit {
  Centimeter = 100, 
  Meter      = 1
};

Rect(int len, int wid, Unit unit) {
  length = len / (int) unit;
  width = wid / (int) unit;
}

Rect obj1(10, 5, Rect::Centimeter);
Rect obj2(10, 5, Rect::Meter);

不能说这违反了规则,但是。。。这不容易读

你为什么不能申报

enum metrics {
  centimeter,
  meter
};
并将其用作构造函数参数?也可能是这样

class Rect {
public:
  static Rect CreateWithMeters(int width, int height);
  static Rect CreateWithCentimenets(int width, int height);
}

根据我的喜好,这两种方法都比当前的代码好。

STL使用这种习惯用法来区分迭代器类型而不是概念

Rect(int len,int wid,enum centimeter){
  length=(len/100);
  width=(wid/100);
}
除了其他人所写的之外,这种逻辑是错误的,因为
Rect(99,99,Rect::cm())
等于
Rect(0,0,Rect::cm())

如果您是在内部存储仪表,请不要提供厘米接口,无论是这种方式还是其他方式。

可能是答案

BOOST_STRONG_TYPEDEF( double, Meter )
BOOST_STRONG_TYPEDEF( double, Centimeters)
BOOST_STRONG_TYPEDEF( double, Furlongs)

class Rect
{
 public:
  Rect(Meter len, Meter wid) : length(len), width(wid) 
  {};

  Rect(Centimeter len, Centimeter wid) : length(len/100), width(wid/100) 
  {};
}

Rect obj1(Meter(10),Meter(5));
Rect obj1(Centimeter(10),Centimeter(5));

在我看来,更简洁的方法是将类的整个接口定义为一个单位(即长度为米),并要求类的用户自己进行转换。在构造函数体中设置成员(应该在ctor初始值设定项列表中初始化)比额外参数的问题更大。我已经处理好了,不应该将integer作为具有厘米枚举类型参数的构造函数的参数类型,将其更改为double。没有什么特别的帮助,小数米仍然被丢弃。您也应该更改私有变量,否则不会有多大帮助。当然,那么你应该改变另一个构造器来保持一致性。好吧,0-99cm是0m,这就是当你四舍五入到最近的米时的情况。将私有变量的类型改为double,大卫:我认为MSN指的是一些常见的实现在内部使用默认参数,如
std::iterator\u traits::iterator\u category
,以区分迭代器对和两个
int
(如
std::vector v(0,0);
)。然而,我认为std库中的一个更好的例子是
new(std::nothrow)
@litb:您的观点很好。但是,当额外的param是一个类型时,通常可以做出编译时决策(因为它基于params类型调用单独的构造函数)。当然,这不是你不知道的;)在这种情况下,我更喜欢你在这里建议的方法,因为它只是选择单位。