在显式实例化的情况下,类模板的成员函数是否可以内联
Can member functions of class templates be inlined in case of explicit instantiation?
给定此配置,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文件中定义的类型。
相关文章:
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 是否有类似std::lower_bound的函数,而不需要排序/分区输入
- 函数作为模板参数,是否对返回类型强制约束
- visual是否可以在c++中创建一个接收无限数量相同类型(或至少相当数量)参数的函数
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 函数是否可以访问传递给main()的参数
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 在这种情况下,java对象是否可以调用本机函数
- 检查函数返回类型是否与STL容器类型值相同
- 根据某个函数是否存在启用模板
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- 无论如何,我可以确定构造函数是否存在吗?
- 是否可以将函数导入命名空间,但不能导出它?
- 返回指向对象的指针的函数调用是否为 prvalue?
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 是否有任何建议来统一函数类型限定符并简化可恶的函数类型?
- 在函数范围内在堆栈上分配的数组在离开函数时是否总是被释放?
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本