我正在审查同事的代码并发现了这一点:
头文件:
template<class T>
class MyClass
{
void Execute();
}
cp文件:
void MyClass<int>::Execute()
{
// something
}
void MyClass<string>::Execute()
{
// something else
}
代码专门化了函数,但没有使用模板专门化语法。我想它工作正常,但它有效吗?
我正在审查同事的代码并发现了这一点:
头文件:
template<class T>
class MyClass
{
void Execute();
}
cp文件:
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
,您将收到链接器错误,因为您没有提供默认实现,也没有提供 for 的专门Execute
化X
。
这个问题已经回答了,但让我提请注意三个案例之间的细微差别。
标题:
template <typename T> struct Foo
{
void f() { /* stuff */ }
};
template <> void Foo<int>::f();
来源:
template <> void Foo<int>::f() { /* ... */ }
在这种情况下,Foo<T>::f()
可以调用任何T
. 一般情况的定义是从模板自动生成的;的定义Foo<int>::f()
是提供的。标题中的特殊化会提醒每个使用翻译单元要查找单独的符号,而不是使用模板。
标题:
template <typename T> struct Foo
{
void f();
};
来源:
template <> void Foo<int>::f() { /* ... */ }
在这种情况下,只能 Foo<int>::f()
使用;其他一切都会导致链接器错误。由于模板中没有函数的定义,每次使用模板都会产生一个新的符号,并且只有一个 forFoo<int>::f()
由所示的翻译单元提供。
标题:
template <typename T> struct Foo
{
void f() { /* stuff */ }
};
来源:
template <> void Foo<int>::f() { /* ... */ }
这违反了一个定义规则,因为现在有多个定义Foo<int>::f()
。
这是显式特化的旧语法。但令我惊讶的是,您使用的编译器仍然接受它(g++ 在 4.0 左右停止)。要符合要求,您需要在专业化前面加上template <>
.
回答最初写的标题中的问题:绝对。在专业化中拥有一组完全不相关的成员也是有效的。
回答代码中的问题:在我看来就像一个编译器错误。template <>
是必需的。