模板类专业化的C ++内联或非内联声明

问题描述

当应该内联专业时,我有点困惑。从this的问题中可以清楚地看出,必须内联每个专业化名称,以避免重复的符号错误。但是,如果我想先声明专业化,该怎么办?

如果我们考虑以下示例:

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;
}

正确的方法是什么?为什么?

解决方法

就像其他问答中提到的那样,专业是它自己的实体。如果您这样做,则在标头中声明特殊化,然后在格式良好的另一个(单个)TU中定义它们。包含该标头的任何TU都会看到intfloat的专业化只是声明。因此,它们的定义可以放在其他地方,就像非模板函数一样。

如果要使用仅标头的库(在此库中内联定义了专用功能),则必须按照ODR的要求使用inline说明符。

在您似乎正在询问的意义上,这两种方法都不是“正确”的方法。每种都有自己的优点和缺点。内联定义函数有助于使库仅作为头文件。但是,如果功能复杂,那么所有依赖关系都将拉入每个包含标头的TU中。同样,更改专业将导致所有这些TU都重新编译。因此,有时也需要隐藏实现。您需要根据具体情况进行判断。

,

正确的方法是什么?为什么?

由于与模板版本相同的原因,这些专业都需要内联。

如果未内联这些符号,您将在所有包含该标头的编译单元中最终获得这些符号的多个定义。

例如

template <>
inline void myClass<int>::myPrint(int myVal) {
    cout << "printing int " << myVal;
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...