构造函数专业化的要求

时间:2014-04-07 21:03:53

标签: c++ templates

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

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)的专业类。

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

3 个答案:

答案 0 :(得分:2)

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

由于您没有为特化提供任何构造函数,因此它提供了期望0 /无参数的默认构造函数。但是,由于您提供了两个争论,编译器正在抱怨。

答案 1 :(得分: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的一个特性。使用此声明,您将引入基类的所有构造函数。但是你可以在派生类中添加更多内容。

答案 2 :(得分:1)

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

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