区分构造函数与默认参数值和空参数列表

时间:2018-02-06 20:52:40

标签: c++

在C ++中,有没有办法区分没有参数的构造函数和一个都具有默认值的参数?

像这样:

class Object {
public:
      Object(int a = 0, int b = 0 ){
      }

      Object(){
      }
};

此外,编译器无法确定应在以下代码示例中使用哪些构造函数:

Object obj;  // which one, Object(int,int) or Object()

2 个答案:

答案 0 :(得分:4)

假设两个c'tors真的异常不同(我怀疑这不太可能,因为两者都应该为对象创建一些“默认状态”),你可以像标准库那样做,当需要消除c'tors的歧义时。您可以根据关闭标签调度使其工作:

class Object {
  public:
  enum class from_ints_t{};
  static constexpr from_ints_t from_ints{};

  Object(from_ints_t, int a = 0, int b = 0 ){
  }

  Object(){
  }
};

现在,默认构造看起来像Object obj;,并且从这些整数的默认值构造看起来像Object obj{Object::from_ints};。没有任何含糊之处。

答案 1 :(得分:1)

只是为了好玩,试图提出类似的建议:

struct Object {
      // SFINAE
      template<class T,
               typename = typename std::enable_if<std::is_same<T, int>::value>::type>
      Object(T a = 0, T b = 0){
          std::cout << "ctor with two ints and defaults" << std::endl;
      }

      Object(){
          std::cout << "empty ctor" << std::endl;
      }
};

int main() {
    Object o1;
    Object o2(8, 9);
    Object o3<int>();    
}

但遗憾的是,不允许以这种方式创建o3,因为显然您无法为构造函数显式指定模板参数,请参阅:Can the template parameters of a constructor be explicitly specified?(答案是:否......)

无论如何,这只是为了好玩。

我在上面的评论中找到了Scab最适合想象的需求的答案 - 使用名为ctor idiom - http://isocpp.org/wiki/faq/ctors#named-ctor-idiom

struct Object {
    static Object emptyCtor() { return Object{}; }
    static Object defaultIntegers() { return Object{0, 0}; }
    static Object create(int a, int b) { return Object{a, b}; }
protected:
    Object(int a, int b){
      std::cout << "ctor with two ints" << std::endl;
    }

    Object(){
      std::cout << "empty ctor" << std::endl;
    }
};

int main() {
    Object o1 = Object::emptyCtor();
    Object o2 = Object::defaultIntegers();
    Object o3 = Object::create(8, 9);
}