我正在审查同事的代码,并发现了以下内容:
头文件:
template<class T>
class MyClass
{
void Execute();
}
Cpp文件:
void MyClass<int>::Execute()
{
// something
}
void MyClass<string>::Execute()
{
// something else
}
这段代码针对函数进行了特化,但没有使用模板特化语法。我猜它能正常工作,但是这样合法吗?
我正在审查同事的代码,并发现了以下内容:
头文件:
template<class T>
class MyClass
{
void Execute();
}
Cpp文件:
void MyClass<int>::Execute()
{
// something
}
void MyClass<string>::Execute()
{
// something else
}
这段代码针对函数进行了特化,但没有使用模板特化语法。我猜它能正常工作,但是这样合法吗?
是的,对于模板类来说,专门化方法是完全有效的。
但是你的语法是错误的,应该是:(抱歉,刚开始没有看到你缺少了template<>
。我假设它在那里并认为你是在问成员函数专门化。)
template<>
void MyClass<int>::Execute()
{
// something
}
template<>
void MyClass<string>::Execute()
{
// something else
}
您只需要在头文件中声明这些函数。如果您还要在头文件中实现它们,您将需要标记它们为inline
以防止多重定义。
调用方法时,将调用最适合该调用的版本。否则,将使用默认版本。
在您的情况下,如果您专门使用类X
来特化模板并尝试调用Execute
,则会出现链接器错误,因为您没有提供默认实现,也没有提供X
的Execute
的特化。
template<>
,这样做完全有效吗? - Kiril Kirovtemplate<>
)。在这种情况下,它是非法的。 - Luchian Grigore标题:
template <typename T> struct Foo
{
void f() { /* stuff */ }
};
template <> void Foo<int>::f();
源代码:
template <> void Foo<int>::f() { /* ... */ }
template <typename T> struct Foo
{
void f();
};
来源:
template <> void Foo<int>::f() { /* ... */ }
Foo<int>::f()
;其他所有的都会导致链接错误。由于模板中没有该函数的定义,每次使用模板都会导致新的符号被生成,而只有Foo<int>::f()
在所示的翻译单元中提供。
头文件:
template <typename T> struct Foo
{
void f() { /* stuff */ }
};
source:
template <> void Foo<int>::f() { /* ... */ }
这是一种违反单一定义规则的行为,因为现在存在多个Foo<int>::f()
的定义。
这是显式特化的旧语法。但我惊讶于您正在使用仍然接受它的编译器(g++在4.0左右停止支持)。为了符合标准,您需要在特化前加上template <>
前缀。
回答标题中的问题:绝对可以。在特化中拥有一组完全不相关的成员也是有效的。
回答代码中的问题:我认为这似乎是编译器的一个错误。需要使用 template <>
。