模板 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 都会看到 intfloat 的专业化只是声明。因此,它们的定义可以放在其他地方,就像 non-template 函数一样。

如果您想要一个仅 header 的库,其中的专用函数是内联定义的,那么您必须使用 inline 说明符,因为 ODR 需要。

从您似乎要问的意义上来说,这两种方法都不是“正确”的方法。每个都有自己的优点和缺点。定义内联函数有助于使库仅 header。但是如果函数很复杂,那么它们的所有依赖项都会被拉入包含 header 的每个 TU 中。此外,更改专业化将导致所有这些 TU 变为 re-compiled。因此,有时将实施隐藏起来也是有好处的。您需要根据具体情况进行判断。