强制隐式类模板实例化以包括所有定义

时间:2018-05-16 14:44:20

标签: c++ templates c++17 template-meta-programming

首先要做的事情是:我使用的是C ++ 17,使用Boost :: Hana会很好,因为我还是在我的代码中使用它。

我试图通过在定义类的文件中使用隐式类模板实例化(默认情况下不实例化成员定义)来模拟显式类模板实例化(即,实例化所有成员'定义)模板。如果这听起来很奇怪,请参阅"为什么有人会这样做?"下面为什么我认为这可能是我实际问题的解决方案。

情况

这是我要在mytemplate.hpp中实例化我的模板的声明:

template<class T>
class MyTemplate {
public:
    void foo();
};

这是mytemplate.cpp中的定义:

#include "mytemplate.hpp"

template<class T>
void
MyTemplate<T>::foo() {}

强制完成隐式实例化

为确保某些类型Whatever的所有MyTemplate<Whatever>成员(在此示例中为MyTemplate<Whatever>::foo())的定义已实例化,我认为我需要在命名空间范围内创建一个情境,对于MyTemplate<Whatever>的每个成员,它都包含:

  

在上下文中引用特化   这需要完全定义的对象类型,或者类类型的完整性会影响语义   该计划

(C ++ 17标准,17.7.1.1)

我的想法是使用继承:如果类Instantiator派生自MyTemplate<Whatever>,则Instantiator的所有成员的定义必须是目标文件的一部分,无论它们是否被使用或不,因为Instantiator不是模板 - 或者我认为。这当然也需要实例化类模板的成员。

考虑修改后的mytemplate.cpp

#include "mytemplate.hpp"

template<class T>
void
MyTemplate<T>::foo() {}

class Instantiator : public MyTemplate<int> {};

编译它不会产生任何符号:

me@mymachine ~/some/dir $ /usr/bin/g++-7 -g -std=c++17 -o mytemplate.cpp.o -c mytemplate.cpp
me@mymachine ~/some/dir $ nm -a mytemplate.cpp.o
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 d .data
0000000000000000 N .debug_abbrev
0000000000000000 N .debug_aranges
0000000000000000 N .debug_info
0000000000000000 N .debug_line
0000000000000000 N .debug_str
0000000000000000 a mytemplate.cpp
0000000000000000 n .note.GNU-stack
0000000000000000 t .text

怎么会这样?为什么Instantiator(及其成员)不属于输出?

您是否看到任何其他方法强制MyTemplate<Whatever>的每个成员进行实例化?

为什么有人会这样做?

mytemplate.{hpp,cpp}之外的某个地方,我有一个类列表,包含在一个元组中,如下所示:

using MyClassList = std::tuple<int, char, bool>;

现在我想要为MyTemplate的模板参数的所有类实例化MyClassList(及其所有成员)的定义 - 而无需手动编写。基本上,如果我更改MyClassList的定义,我就不想触及mytemplate.{hpp,cpp}。因此,我不能使用显式实例化。我也不想在其使用的任何地方加入mytemplate.cpp,因为我的编译单元的大小似乎已经存在问题。

显然,这意味着我无法逐字使用上述派生类技巧,因为我需要手动列出所有派生类,但该问题应该可以通过递归类模板来解决。

0 个答案:

没有答案