模板 class 特化的 C++ 内联或非内联声明
C++ inline or not inline declarations of template class specializations
当一个人应该内联专业化时,我有点困惑。从 问题可以清楚地看出,必须内联每个特化以避免重复的符号错误。但是,如果我想先声明专业化,那会有什么改变呢?
如果我们考虑这个例子:
template<typename T>
class myClass
{
public:
static void myPrint(T myVal);
}
#include "declarations.hpp"
//-----------------------------------------------
//declarations.hpp
template<typename T>
void myClass<T>::myPrint(T myVal)
{
cout << "printing unknown type " << myVal;
}
template <>
void myClass<int>::myPrint(int myVal); //inline here or in definition?
template <>
void myClass<float>::myPrint(float myVal); //inline here or in definition?
//-----------------------------------------------
//some_file_that_includes_myClass_header.cpp
template <>
void myClass<int>::myPrint(int myVal) //inline or no inline?
{
cout << "printing int " << myVal;
}
//-----------------------------------------------
//some_other_file_that_includes_myClass_header.cpp
template <>
void myClass<float>::myPrint(float myVal) //inline or no inline?
{
cout << "printing float " << myVal;
}
执行此操作的正确方法是什么,为什么?
What would be the correct way to do this, and why?
这些特化也需要内联,原因与模板化版本相同。
如果这些符号没有内联,您最终会在任何编译单元中得到这些符号的多个定义,其中包括 header。
例如
template <>
inline void myClass<int>::myPrint(int myVal) {
cout << "printing int " << myVal;
}
就像其他问答提到的那样,专业化是它自己的实体。如果你这样做,在 header 中声明专业化,然后在另一个(单个)TU 中定义它们,即 well-formed。任何包含 header 的 TU 都会看到 int
和 float
的专业化只是声明。因此,它们的定义可以放在其他地方,就像 non-template 函数一样。
如果您想要一个仅 header 的库,其中的专用函数是内联定义的,那么您必须使用 inline
说明符,因为 ODR 需要。
从您似乎要问的意义上来说,这两种方法都不是“正确”的方法。每个都有自己的优点和缺点。定义内联函数有助于使库仅 header。但是如果函数很复杂,那么它们的所有依赖项都会被拉入包含 header 的每个 TU 中。此外,更改专业化将导致所有这些 TU 变为 re-compiled。因此,有时将实施隐藏起来也是有好处的。您需要根据具体情况进行判断。
当一个人应该内联专业化时,我有点困惑。从
如果我们考虑这个例子:
template<typename T>
class myClass
{
public:
static void myPrint(T myVal);
}
#include "declarations.hpp"
//-----------------------------------------------
//declarations.hpp
template<typename T>
void myClass<T>::myPrint(T myVal)
{
cout << "printing unknown type " << myVal;
}
template <>
void myClass<int>::myPrint(int myVal); //inline here or in definition?
template <>
void myClass<float>::myPrint(float myVal); //inline here or in definition?
//-----------------------------------------------
//some_file_that_includes_myClass_header.cpp
template <>
void myClass<int>::myPrint(int myVal) //inline or no inline?
{
cout << "printing int " << myVal;
}
//-----------------------------------------------
//some_other_file_that_includes_myClass_header.cpp
template <>
void myClass<float>::myPrint(float myVal) //inline or no inline?
{
cout << "printing float " << myVal;
}
执行此操作的正确方法是什么,为什么?
What would be the correct way to do this, and why?
这些特化也需要内联,原因与模板化版本相同。
如果这些符号没有内联,您最终会在任何编译单元中得到这些符号的多个定义,其中包括 header。
例如
template <>
inline void myClass<int>::myPrint(int myVal) {
cout << "printing int " << myVal;
}
就像其他问答提到的那样,专业化是它自己的实体。如果你这样做,在 header 中声明专业化,然后在另一个(单个)TU 中定义它们,即 well-formed。任何包含 header 的 TU 都会看到 int
和 float
的专业化只是声明。因此,它们的定义可以放在其他地方,就像 non-template 函数一样。
如果您想要一个仅 header 的库,其中的专用函数是内联定义的,那么您必须使用 inline
说明符,因为 ODR 需要。
从您似乎要问的意义上来说,这两种方法都不是“正确”的方法。每个都有自己的优点和缺点。定义内联函数有助于使库仅 header。但是如果函数很复杂,那么它们的所有依赖项都会被拉入包含 header 的每个 TU 中。此外,更改专业化将导致所有这些 TU 变为 re-compiled。因此,有时将实施隐藏起来也是有好处的。您需要根据具体情况进行判断。