类模板中的模板构造函数 - 如何为第二个参数显式指定模板参数?
尝试显式指定构造函数2的模板参数时,编译错误。 如果我真的想要显式调用构造函数2,我应该怎么做?
请注意,当您想要明确指定删除器类型时,boost :: shared_ptr的情况相同。
N.B。对于非 - 构造函数foo(),显式指定工作正常。
N.B我知道它工作正常没有为构造函数2明确指定第二个作为模板参数推论通常只是工作正常,我只是好奇如何明确指定它。
template<class T> class TestTemplate {
public:
//constructor 1
template<class Y> TestTemplate(T * p) {
cout << "c1" << endl;
}
//constructor 2
template<class Y, class D> TestTemplate(Y * p, D d) {
cout << "c2" << endl;
}
template<class T, class B>
void foo(T a, B b) {
cout << "foo" << endl;
}
};
int main() {
TestTemplate<int> tp(new int());//this one works ok call constructor 1
//explicit template argument works ok
tp.foo<int*, string>(new int(), "hello");
TestTemplate<int> tp2(new int(),2);//this one works ok call constructor 2
//compile error when tried to explicit specify template argument for constructor 2
//How should I do it if I really want to explicit call constructor 2?
//TestTemplate<int*, int> tp3(new int(), 2); //wrong
//TestTemplate<int*> tp3<int*,int>(new int(), 2); //wrong again
return 0;
}
答案 0 :(得分:24)
修复代码,以下方法可行:
template<class T> class TestTemplate {
public:
//constructor 1
template<class Y> TestTemplate(Y * p) {
cout << "c1" << endl;
}
//constructor 2
template<class Y, class D> TestTemplate(Y * p, D d) {
cout << "c2" << endl;
}
template<class A, class B>
void foo(A a, B b) {
cout << "foo" << endl;
}
};
int main() {
TestTemplate<int> tp(new int());
tp.foo<int*, string>(new int(), "hello");
TestTemplate<int> tp2(new int(),2);
}
您不能将T
用于类模板参数和构造函数模板参数。但是,从[14.5.2p5]来回答你的问题:
因为显式模板参数列表跟在函数后面 模板名称,因为转换成员函数模板和 不使用a调用构造函数成员函数模板 函数名称,没有办法提供显式模板 这些函数模板的参数列表。
因此,您无法为构造函数显式指定模板参数。
答案 1 :(得分:9)
您无法显式指定构造函数的模板参数,因为构造函数本身没有名称,因此没有语法。
但是,您可以通过
确保正确的模板参数推断投射实际参数,和/或
引入“人为的”额外参数,以便在必要时携带类型信息和/或
使用工厂功能。
例如,您可以定义
template< class Type > struct TypeCarrier{ typedef Type T; };
struct MyClass
{
template< class Type >
MyClass( TypeCarrier< Type > ) { ... }
};
...
MyClass o( TypeCarrier<int>() );
但不要被这些技术所淹没。
相反,如果显然需要明确指定构造函数模板参数,请考虑设计是否真的合理?
如果你反思 ,你可以使用一些更简单的设计吗?
答案 2 :(得分:4)
您可以显式指定调用foo
的模板参数,因为这些成员函数foo
具有名称 - 模板参数是该名称的一部分。
这对构造函数不起作用,因为构造函数没有名称。你不能(直接)调用构造函数。当然,在创建对象时会调用构造函数,但会生成调用代码。