【问题标题】:Requirement of constructor specialization构造函数专业化要求
【发布时间】:2014-04-07 21:03:53
【问题描述】:

我尝试专门化构造函数具有模板化参数的类,但我不想为每个模板专门化专门化构造函数。例如:

template<typename A, typename B>
struct S{
    S( A _a, B _b ) : a(_a), b(_b){}
    A a;
    B b;
};
//Partial specialization
template<typename A>
struct S<A, int>{
};
int main( int argc, char* argv[] ) {
    S<char, float> s0('1', 1.0);
    S<char, int> s1('1', 1);    //Compilation error
    return 0;
}

编译错误:

main.cpp:13:24: error: no matching function for call to ‘S<char, int>::S(char, int)’
  S<char, int> s1('1', 1);
                        ^
main.cpp:13:24: note: candidates are:
main.cpp:9:8: note: S<char, int>::S()
 struct S<A, int>{
        ^
main.cpp:9:8: note:   candidate expects 0 arguments, 2 provided
main.cpp:9:8: note: S<char, int>::S(const S<char, int>&)
main.cpp:9:8: note:   candidate expects 1 argument, 2 provided

如果我附加构造函数,编译将成功完成:

S( A _a, int _b ) : a(_a), b(_b){}

到具有所有领域(a 和 b)的专业类。

为什么它不起作用?为什么没有自动生成构造函数?

【问题讨论】:

  • 您可以使用通用基类(模板)+ 继承 ctor 作为解决方法(在 C++11 中)。

标签: c++ templates


【解决方案1】:

每个类模板部分特化都是一个单独的模板。您必须为类模板部分特化的每个成员提供定义。因此编译器看不到通用类模板的构造函数,即您也必须为规范化提供构造函数。

由于您没有为专业化提供任何构造函数,因此它提供了默认构造函数,该构造函数需要 0/无参数。但是,由于您提供了 2 个论点,因此编译器正在抱怨。

【讨论】:

    【解决方案2】:

    我不知道什么你想专攻,但正如@dyp 所指出的,这是一种避免重复成员和构造函数的方法:

    template<typename A, typename B>
    struct Base
    {
        Base(A a, B b) : a(a), b(b) { }
        A a;
        B b;
    };
    
    template<typename A, typename B>
    struct S : Base<A, B>
    {
        using Base<A, B>::Base;
        // extensions...
    };
    
    template<typename A>
    struct S<A, int> : Base<A, int>
    {
        using Base<A, int>::Base;
        // specialized extensions...
    };
    

    using 基本构造函数是 C++11 特性。通过此声明,您将引入基类的 all 构造函数。但是您可以在派生类中添加更多内容。

    【讨论】:

    • using Base::Base; 应该是 using Base&lt;A, B&gt;::Base;using Base&lt;A, int&gt;::Base;
    【解决方案3】:

    编译器正在使用专门的模板类。哪个没有您定义的构造函数。所以它使用编译器生成的默认值。即

    S<char, int>::S()  // default constructor
    S<char, int>::S(const S<char, int>&)  // copy constructor
    

    所以你现在的专业课差不多是这样的

    template<typename A>
    struct S {
        S();
        S(const S&);
    };
    

    你需要的是类似的东西

    template<typename A>
    struct S<A, int> {
        S(A a, int i) { .... }
    };
    

    如果你真的想要避免为每个类定义构造函数,只需使用类似这样的继承模式

    template<typename A>
    struct S_int : public S<A, int> {};
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-14
      • 1970-01-01
      • 2015-03-12
      • 1970-01-01
      • 2016-07-02
      相关资源
      最近更新 更多