在显式实例化的情况下,类模板的成员函数是否可以内联

Can member functions of class templates be inlined in case of explicit instantiation?

本文关键字:是否 函数 成员 实例化 情况下      更新时间:2023-10-16

给定此配置,doSth()是否可以内联?

// A.h
template<typename T>
struct A
{
    void doSth();
};

// A.cpp
template<typename T>
void A<T>::doSth() { /* do something */ }
template class A<bool>;
template class A<int>;

// main.cpp
#include "A.h"
int main()
{
    A<bool> a;
    a.doSth();
}

如果答案是否定的,我会在.tpp文件中定义我的成员函数,并将其包含在"a.h"的末尾,但对于.cpp文件中的非内联版本,这看起来很奇怪,所以我想避免这种情况。

大多数编译器都无法与这种代码排列内联。ICC编译器文档声称,它支持以这样一种方式调用,即内联AFTER您首先以不同的方式构建,然后收集分析数据,然后将分析数据反馈给跨模块优化构建。我只是做了一些适度的尝试来实现这一点,而且它只在游戏大小的项目中有效,而在任何真实的项目中都无效。

对于普通编译,您应该为想要内联的函数定义提供额外的文件,但可能不应该将其包含在A.h的末尾,而应该将A.h包含在它的开头,并将它包含在真正需要它的选定cpp文件中。

我更喜欢

// A.h
#ifndef A_H
#define A_H
template<typename T>
struct A
{
    inline void doSth();
};
#endif
// A.tpp
#ifndef A_TPP
#define A_TPP
#include "A.h"
template<typename T>
inline void A<T>::doSth() { /* do something */ }
#endif
// Various other .h files that need to know what is declared in A
#include "A.h"
// Only cpp files that need what is defined in A.tpp
#include "A.tpp"

我忘记了这个选项,也忘记了哪些编译器有这样的选项,但在.h文件中几乎多余地使用inline与编译器选项一起使用,即如果函数是以的方式声明的,则使用,并且未定义,则会引发编译时错误。

如果没有该选项,链接时间错误将更难读取,但它确实会告诉您哪个.cpp需要包含.tpp,但没有包含。

你绝对可以。您还忘记了结构定义末尾的;

struct a
{
    // Whatever
};

应该是这样的。

Visual Studio确实允许以这种方式进行内联,但它将可以实例化的类型限制为仅在A.cpp文件中定义的类型。

相关文章: