我尝试将构造函数具有模板化参数的类专门化,但我不想为每个模板特化专门化构造函数。例如:
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)的专业类。
为什么它不起作用?为什么没有自动生成构造函数?
答案 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> {};