【问题标题】:Differentiate between constructor with default argument value and empty argument list区分具有默认参数值的构造函数和空参数列表
【发布时间】:2018-02-06 20:52:40
【问题描述】:

在 C++ 中,有什么方法可以区分没有参数的构造函数和所有参数都具有默认值的构造函数?

像这样:

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

      Object(){
      }
};

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

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

【问题讨论】:

  • 不。具有所有 default 参数的构造函数是 default 构造函数。
  • 如果两个参数都可以有默认值,这可能意味着您在两个 c'tors 中都有重复的行为。
  • 即使编译成功,结合默认参数值重载方法也不是一个好主意...
  • 你可能会觉得有趣的是看看这个来解决你的消歧问题isocpp.org/wiki/faq/ctors#named-ctor-idiom
  • 听起来不粗鲁,但为什么两者都有,也就是说,为了你的程序,两者有什么区别,让你想试试这个?

标签: c++


【解决方案1】:

假设这两个 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};。没有歧义。

【讨论】:

  • 您使用强类型枚举而不是 from_ints 的简单类的原因是什么?
  • @davidhigh - 习惯的力量。一个类也会做同样的事情,甚至可能会更好。
【解决方案2】:

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

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);
}

【讨论】:

    猜你喜欢
    • 2017-09-27
    • 2016-09-05
    • 2016-02-08
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    相关资源
    最近更新 更多