单独的汇编和模板显式实例化
Separate compilation and template explicit instantiation
摘要
这个问题是关于在几个不同的翻译单元中实现单个模板类实例化的单独汇编。
问题
对于非模板类,可以将定义放在几个.cpp文件中并单独编译。例如:
文件A.H:
class A {
public:
void func1();
void func2();
void func3() { /* defined in class declaration */}
}
file a1.cpp:
void A::func1() { /* do smth */ }
文件A2.CPP:
void A::func2() { /* do smth else */ }
现在,我尝试在模板类中做类似的事情。由于我确切地知道我需要哪些实例,因此我明确实例化模板。我正在分别编译每个实例化,因为成员函数包含相当大的数学表达式,这可能会在高优化水平上大大减慢编译器。所以我尝试了以下内容:
file ta.h:
template <typename T>
class TA {
public:
void func1();
void func2();
void func3() { /* defined in class declaration */}
}
file ta1.cpp:
template <typename T>
void TA<T>::func1() { /* do smth */ }
template class TA<sometype>;
file ta2.cpp:
template <typename T>
void TA<T>::func2() { /* do smth else */ }
template class TA<sometype>;
它与Linux上的Clang和GCC一起使用,但在重复符号错误期间链接时与Mac上的GCC失败(在此示例中,由于func3,该示例在TA1.CPP和TA2.CPP中都进行了实例化)。
)。然后我在标准中偶然发现了这句话:
C 11.14.7,第5段:
对于给定的模板和一组给定的模板arguments,
- 明确的实例化定义最多应在一个程序中出现,
- ...
这是否意味着即使使用显式实例化,也无法(不允许)单独的模板类的汇编(显然是不可能使用隐式实例化的)?
ps我不在乎,因为我得到了答案,但是谁认为在这里回答的人https://stackoverflow.com/questions/495021/why-can-templates-only-only-only-be-implemented in - 头部文件是错误的。
又一次查看标准后,在我看来,唯一合理的选择是使用单个显式模板类实例化与少数"困难"函数的显式成员函数实例化结合。
此(根据14.7.2p9)将实例化类和所有已定义的成员(到目前为止)(其中应包括所有内容"困难"成员)。那么这些选定的成员可以在包含其定义的其他翻译单元中明确实例化。
这会使我的示例看起来像下面(假设 ta1.cpp 包含简单的功能,并且 ta 中唯一的"困难"功能是 func2
file ta1.cpp:
template <typename T>
void TA<T>::func1() { /* "simple" function definition */ }
template class TA<sometype>; /* expl. inst. of class */
file ta2.cpp:
template <typename T>
void TA<T>::func2() { /* "difficult" function definition */ }
template void TA<sometype>::func2(); /* expl. inst. of member */
此方法要求我们为每个"困难"功能编写明确的实例化定义,这很繁琐,但也使我们三思而后行。
免责声明
什么时候有用?不经常。正如这里提到的其他人所述,不建议将类的定义分为几个文件。在我的特殊情况下,"困难"功能包含了关于非平凡类实例的复杂数学操作。C 模板并不以快速汇编速度而闻名,但在这种情况下,它是难以忍受的。这些功能相互调用,该功能会在扩展/内部嵌入式运算符/模板/等的长时间内存和耗费的旅程中发送编译器,以优化其所看到的所有内容,并有所改善,但要持续数小时。在单独文件中隔离某些函数的这种窍门速度将汇编加速20次(并同样可以并行化)。
模板的单独汇编很棘手,但允许。您不能做的是明确实例化多个翻译单元中的类型,就像不能在两个翻译单元中定义相同函数的方式一样。
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 检查某些类型是否是模板类 std::optional 的实例化
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- 模板化类构造函数的模板实例化
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 受约束的成员函数和显式模板实例化
- 对显式实例化的模板函数的未定义引用
- 单独的汇编和模板显式实例化