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

分离编译和模板显式实例化

桂和同
2023-03-14

摘要
这个问题是关于在几个不同的翻译单元中实现单个模板类实例化的单独编译。

class A {
public:
  void func1();
  void func2();
  void func3() { /* defined in class declaration */}
}
void A::func1() { /* do smth */ }

文件A2.cpp:

void A::func2() { /* do smth else */ }

现在我尝试用模板类做类似的事情。因为我确切地知道我将需要哪些实例,所以我显式地实例化模板。我单独编译每个实例化,因为成员函数包含相当大的数学表达式,这可能会在高优化级别上大大降低编译器的速度。所以我尝试了以下方法:

文件ta.h:

template <typename T>
class TA {
public:
  void func1();
  void func2();
  void func3() { /* defined in class declaration */}
}
template <typename T>
void TA<T>::func1() { /* do smth */ }
template class TA<sometype>;
template <typename T>
void TA<T>::func2() { /* do smth else */ }
template class TA<sometype>;

这是否意味着即使使用显式实例化也不可能(不允许)单独编译模板类(隐式实例化显然不可能)?

我不在乎,因为我已经得到了我的答案,但是无论谁认为它在这里得到了答案https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file都是错误的。

共有1个答案

萧霍英
2023-03-14

在重新审视标准之后,我认为唯一合理的选择是使用单个显式模板类实例化与少量“困难”函数的显式成员函数实例化相结合。

这(根据14.7.2p9)将实例化这个类和到目前为止已经定义的所有成员(应该包括除“困难”成员之外的所有内容)。然后,那些选定的成员可以在包含其定义的其他翻译单元中显式实例化。

这将使我的示例如下所示(假设ta1.cpp包含简单的函数,并且TA中唯一“困难”的函数是func2)

template <typename T>
void TA<T>::func1() { /* "simple" function definition */ }

template class TA<sometype>; /* expl. inst. of class */
template <typename T>
void TA<T>::func2() { /* "difficult" function definition */ }

template void TA<sometype>::func2(); /* expl. inst. of member */

免责声明

什么时候有用?不经常。正如其他人在这里提到的,不建议将类的定义拆分到几个文件上。在我的特殊情况下,“困难”函数包含对非平凡类实例的复杂数学运算。C++模板并不以编译速度快而闻名,但在这种情况下,它是无法忍受的。这些函数相互调用,这使得编译器需要展开/内联重载的运算符/模板/等来优化它所看到的一切,这是一个漫长而消耗内存的旅程,几乎没有任何改进,但使编译持续数小时。这种将一些函数隔离在单独文件中的技巧将编译速度提高了20倍(并允许并行)。

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

  • 例1 如前所述,上面的编译和链接没有问题。然而,在实际应用程序中,我有许多函数模板和许多枚举成员。因此,我试图通过将成员分组到一个新类中来使我的生活变得更轻松,这个类本身依赖于模板参数,并为每个枚举值显式地实例化该类。 例2 编辑:用户2B-T通过https://www.onlinegdb.com/hygr7w0fv_提供了这些示例,供人们进行实验。

  • 主要内容:编译JRXML文件,预览Jasper文件我们在上一章中生成了 JasperReport 模板(JRXML 文件)。该文件不能直接用于生成报表。它必须编译为 JasperReport 的原生二进制格式,称为Jasper文件。在编译时,我们将 JasperDesign 对象转换为 JasperReport 对象。 接口net.sf.jasperreports.engine.design.JRCompiler在编译过程中起着核心作用。该接口有

  • 你可能有兴趣知道,Vue 的模板实际是编译成了 render 函数。这是一个实现细节,通常不需要关心,但如果你想看看模板的功能是怎样被编译的,你会发现会非常有趣。下面是一个使用Vue.compile来实时编译模板字符串的简单 demo: <div> <header> <h1>I'm a template!</h1> </header> <p v-if="message">

  • 尽管 PHP 不断升级为成熟的、面向对象的语言,但它作为模板语言 没有改善多少。编译型模板,比如 Twig、Brainy 或 Smarty,提供了模板专用的新语法,填补了这片空白。从自动转义到继承以及简化控制结构,编译模板设计地更容易编写,可读性更高,同时使用上也更加的安全。编译型模板甚至可以在不同的语言中使用,Mustache 就是一个很好的例子。由于这些模板需要编译,在性能上会带来一些轻微的影

  • 如果你在 <script> 标签中编写模板,并且设置了特定的属性,那么 Framework7 会自动帮你编译所有的模板: <script type="text/template7" id="myTemplate"> <p>Hello, my name is {{name}} and i am {{age}} years old</p> </script> 其中: type="text/t