为类声明中的模板类定义成员函数与外部之间是否存在差异?
内部定义:
template <typename T>
class A
{
public:
void method()
{
//...
}
};
在外面定义:
template <typename T>
class B
{
public:
void method();
};
template <typename T>
void B<T>::method()
{
//...
}
对于非模板类,这是内联和非内联方法之间的区别。模板类也是如此吗?
我的大多数同事的默认设置是在类中提供定义,但我总是更喜欢类外的定义。我的偏好是否合理?
编辑:请假设所有上述代码都在该类的头文件中提供。
答案 0 :(得分:2)
是的,模板类完全相同。
模板类的方法定义通常首选内联的原因是,对于模板,在实例化模板时,整个定义必须是可见的。
因此,如果将函数定义放在某个单独的.cpp文件中,则会出现链接器错误。
唯一的通用解决方案是通过在类内部或在inline
关键字外部定义函数来使函数内联。但在任何一种情况下,它必须在调用函数的任何地方都可见,这意味着它通常必须与类定义在同一个头中。
答案 1 :(得分:1)
除了必须输入更多内容之外没有区别。这包括template
位,inline
,并且在引用类时必须使用更多“精心”的名称。例如
template <typename T> class A {
A method(A a) {
// whatever
}
};
template <typename T> inline A<T> A<T>::method(A a) {
// whatever
}
请注意,当在内部定义方法时,您可以在引用<T>
时省略模板参数列表A<T>
,并使用A
。在外部定义时,必须在返回类型和方法名称中使用“完整”名称(但不在参数列表中)。
答案 2 :(得分:0)
我知道这一点......我认为它必须是一些对你有帮助的东西吗?
defining a member function outside of its template
提供模板类的成员函数的定义是不正确的:
// This might be in a header file:
template <typename T>
class xyz {
void foo();
};
// ...
// This might be later on in the header file:
void xyz<T>::foo() {
// generic definition of foo()
}
出于某些原因,这是错误的。这就是:
void xyz<class T>::foo() {
// generic definition of foo()
}
正确的定义需要template关键字和声明类模板定义的模板参数。所以这给了:
template <typename T>
void xyz<T>::foo() {
// generic definition of foo()
}
请注意,还有其他类型的模板指令,例如成员模板等,每个都采用自己的形式。重要的是要知道你有哪些,所以你知道如何写每种口味。这是特别的,因为一些编译器的错误消息可能不清楚是什么问题。当然,要获得一本好的和最新的书。
如果模板中有嵌套的成员模板:
template <typename T>
struct xyz {
// ...
template <typename U>
struct abc;
// ...
};
如何在xyz之外定义abc?这不起作用:
template <typename U>
struct xyz::abc<U> { // Nope
// ...
};
也不是这样:
template <typename T, typename U>
struct xyz<T>::abc<U> { // Nope
// ...
};
你必须这样做:
template <typename T>
template <typename U>
struct xyz<T>::abc {
// ...
};
请注意,...abc
不是...abc<U>
,因为abc是“主要”模板。 IOWs,这不好:
//这里不允许: 模板模板struct xyz :: abc {};