我在类功能下尝试了以下专业化,但它给了我错误。
enum SpecializedType
{
TypeA,
TypeB
};
class TestFunctionSpecialization
{
public:
template<SpecializedType T> void print(const T& t)
{
}
};
template<> void TestFunctionSpecialization::print<TypeA>(const TypeA& t)
{
}
错误是
../src/TestFunctionSpecialization.h:22:49: error: ‘T’ does not name a type
template<SpecializedType T> void print(const T& t)
^
../src/TestFunctionSpecialization.h:28:65: error: ‘TypeA’ does not name a type
template<> void TestFunctionSpecialization::print<TypeA>(const TypeA& t)
我该如何正确地进行这项专业化?
答案 0 :(得分:1)
有两种类型的模板参数,您可以将它们混合在一起:
使用关键字class
或typename
引入的类型参数。例如:
template <typename T> void foo(T arg) {}
使用类型引入的值参数,例如:
template <int N> int foo() { return N; }
您的代码将其声明为值参数,但随后将其用作类型。这是错误的,编译器这样说:
error: ‘T’ does not name a type
我们可以让您的代码只需删除参数即可编译:
enum SpecializedType
{
TypeA,
TypeB
};
class TestFunctionSpecialization
{
public:
template<SpecializedType T> void print()
{
//T is a constant, not a type
}
};
template<> void TestFunctionSpecialization::print<TypeA>()
{
//no T declared here!
}
但是这个特殊的代码似乎不必要地复杂,为什么不将T
作为普通参数传递来打印并避免模板一起使用:
void print(SpecializedType t)
{
//use t
}
答案 1 :(得分:0)
编译器明确表示你不能const TypeA& t
,因为TypeA
不是类型,而是值参数。例如,考虑声明const 10& t
(而不是const int& t
):你要做的就是错误。
如果您想要专注于TestFunctionSpecialization::print
,那么您实际上已经接近了。忘记将t
传递给方法。你不会需要它,因为你已经传递了一个(模板)参数来告诉编译器你想要使用哪种方法:
template<> void TestFunctionSpecialization::print<TypeA>()
{
// implementation for the "TypeA" version
}
看一个简单的例子here。
答案 2 :(得分:0)
在template<SpecializedType T> void print(const T& t)
中,T
不是模板类型参数,而是非类型模板参数。你不能将它作为一种类型使用,它是一种价值。所以你不能写const &T
。