【问题标题】:Default template parameter in constructor构造函数中的默认模板参数
【发布时间】:2009-05-06 21:50:52
【问题描述】:

所以我有这段代码,为了方便起见,我希望它的构造函数的默认参数是 int 类型和 0。(我的项目的一个类中有更多参数,其中一个是可选的,我没有'不想写两次构造函数,因为它很大)

class mama{
    public:
    template<typename x> mama(x i=int(0)){}
};

int main(){
    mama x;
}

这不起作用,因为它说它找不到构造函数,所以我还有其他方法可以做到这一点吗?

error: no matching function for call to ‘mama::mama()'
note: candidates are: mama::mama(const mama&)

【问题讨论】:

    标签: c++ constructor templates default parameters


    【解决方案1】:

    请注意,函数模板不允许使用默认模板参数。为什么不创建类模板?

    template <class T=int>
    class mama{
        public:
        mama<T>(T i=0){}
    };
    
    int main(){
        mama<> x; // no argument based template parameter deduction possible
    }
    

    【讨论】:

      【解决方案2】:

      将您的构造函数重构为私有初始化函数和包装构造函数,然后添加默认值,如下所示:

      class mama {
        private:
          template<typename x> void init(x i) { /* ... */ }
        public:
          template<typename x> mama(x i) { init(i); }
          mama() { init((int)0); }
      };
      

      【讨论】:

      • 您的 ctor 已模板化这一事实强烈提示我将整个班级模板化。 YMMV!
      • 可能;我无法想象如果不将类模板化,这样的模板化构造函数将如何有用,但这给出了原始问题所要求的内容,并且其他人涵盖了将类设为模板:)
      • 其实模板化的构造函数很有用。例如 boost::shared_ptr、boost::any 和可能实现的句柄主体或类似模式使用此技术。
      • +1 这解决了第二个问题,即不必复制/粘贴代码块来提供多个类似的构造函数,方法是将初始化代码重构为单独的方法,并使用所需参数从构造函数调用它。维护更灵活。
      【解决方案3】:

      默认值就像重载一样,所以...

      class mama{
      public:
          template<typename x> mama(x i){}
          mama(int i = 0) {}
      };
      

      当您创建不带参数的 mama 时,具有默认 int 的构造会在任何模板化构造函数之前匹配。

      【讨论】:

      • 是的,但这并不能避免代码重复。 Csiz 想要一个构造函数。
      • 如果您不想将构造函数主体两次写入函数,就像 bdonlan 建议的那样。但是,如果您以后想使用 bdonlan 的解决方案专门化 mama::mama(int)(使用不带参数的默认构造函数,而不是带 int 且默认为 0 的构造函数),您必须添加另一个构造函数才能做到这一点。
      猜你喜欢
      • 2016-03-01
      • 2014-05-18
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 2012-02-15
      • 1970-01-01
      • 1970-01-01
      • 2010-12-10
      相关资源
      最近更新 更多