当前位置: 首页 > 知识库问答 >
问题:

自动化显式模板实例化

潘坚白
2023-03-14

例1

/* test.h
   Contains the function-template-declaration, not the implementation.
*/

enum class Enum
{
    Member1,
    Member2,
    Member3
};

struct Type
{
    template <Enum Value>
    int get() const;
};
/* test.cpp
   Only the declaration is visible -> needs to link against correct instantiation.
*/

#include "test.h"

int main() {
    std::cout << Type{}.get<Enum::Member1>() << '\n';
}
/* test.tpp 
   .tpp extension indicates that it contains template implementations.
*/

#include "test.h"

template <Enum Value>
int Type::get() const
{
    return static_cast<int>(Value); // silly implementation
}
/* instantiate.cpp
   Explicitly instantiate for each of the enum members.
*/

#include "test.tpp"

template int Type::get<Enum::Member1>() const;
template int Type::get<Enum::Member2>() const;
template int Type::get<Enum::Member3>() const;

如前所述,上面的编译和链接没有问题。然而,在实际应用程序中,我有许多函数模板和许多枚举成员。因此,我试图通过将成员分组到一个新类中来使我的生活变得更轻松,这个类本身依赖于模板参数,并为每个枚举值显式地实例化该类。

例2

// instantiate.cpp

#include "test.tpp"

template <Enum Value>
struct Instantiate
{
    using Function = int (Type::*)() const;
    static constexpr Function f1 = Type::get<Value>;
   
    // many more member-functions
};

template class Instantiate<Enum::Member1>;
template class Instantiate<Enum::Member2>;
template class Instantiate<Enum::Member3>;
// instantiate.cpp

#include "test.tpp"

template <Enum Value>
struct Instantiate { /* same as before */ };

template <Enum ... Pack>
struct InstantiateAll:
    Instantiate<Pack> ...
{};

template class InstantiateAll<Enum::Member1, Enum::Member2, Enum::Member3>; 

编辑:用户2B-T通过https://www.onlinegdb.com/hygr7w0fv_提供了这些示例,供人们进行实验。

共有1个答案

卫高谊
2023-03-14

如果编译器发现代码没有被引用,即使是静态初始化有副作用,它也可以消除它,我认为在您的示例中就是这种情况。它可以“证明”这些类实例没有被使用,因此副作用就消失了。

对于一个非标准的解决方案,但它适用于G++(可能是clang,但未经测试),是用“used”属性标记静态数据成员:

template <Enum Value>
struct Instantiate
{
    using Function = int (Type::*)() const;
    static constexpr Function f1 __attribute__((used)) = &Type::get<Value>;
   
    // many more member-functions
};

更新

 类似资料:
  • 根据我的尝试和错误,答案似乎是否定的,这是一个简单的 将为班上的所有成员工作。然而,我读过的代码建议不是这样,如果能给出具体的答案,我将不胜感激。

  • 摘要 这个问题是关于在几个不同的翻译单元中实现单个模板类实例化的单独编译。 文件A2.cpp: 现在我尝试用模板类做类似的事情。因为我确切地知道我将需要哪些实例,所以我显式地实例化模板。我单独编译每个实例化,因为成员函数包含相当大的数学表达式,这可能会在高优化级别上大大降低编译器的速度。所以我尝试了以下方法: 文件ta.h: 这是否意味着即使使用显式实例化也不可能(不允许)单独编译模板类(隐式实例

  • 我正在从事一个C语言的项目,当我显式实例化模板类时,很难理解模板类的哪些成员被显式实例化。我编写了以下文件,然后使用Visual C 2008 Express Edition的发布配置编译该文件,然后将其放入反汇编程序。 忽略这个文件目前并不真正需要模板,这可以很好地编译。我将exe放入反汇编程序,它告诉我该测试 这导致测试

  • [dcl.spec.auto]/14国[强调我的]: 显式实例化声明不会导致使用占位符类型声明的实体的实例化,但也不会阻止根据需要对该实体进行实例化以确定其类型。[示例: -结束示例] 和[temp.explicat]/11声明[强调我的]: 现在,考虑我们是否在类模板中的friend声明中定义了friend函数: 如果在同一翻译单元中实例化了的多个专门化,则将违反[basic.def.odr]/

  • 我有一个成员功能模板如下: 当我编译它时,我得到了一个链接错误,所以我添加了一些它们的显式实例化。 编译器错误消息: /usr/include/c /9/variant:在“constexpr const _Tp”的实例化中 断言失败:T应该在替代项中只出现一次 我为什么得到这个?如何解决?

  • 在本文中,他们说(c)是(b)的显式专门化。我的疑问是,为什么我们不能说它是(a)的显式专门化?因为我们可以为任何特定类型专门化模板。所以,当专门化int*时,为什么他们说(c)显式专门化(b)。 任何评论都将有助于理解事情。