如何在C ++ 20模块中使用模板显式实例化? [英] How to use template explicit instantiation with C++20 modules?

查看:127
本文介绍了如何在C ++ 20模块中使用模板显式实例化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此答案中所述所述,模板实例化通过不需要为每个新模板重新编译模板而减少了编译时间和大小。输入使用它们的每个新文件。

As explained in this answer template instantiation allows reducing compilation times and sizes by not requiring templates to be recompiled for every new type in every new file that uses them.

我也很高兴 C ++ 20模块应该提供一个干净的解决方案,以将模板暴露给外部项目并减少hpp / cpp重复。

I'm also excited about how C++20 modules should provide a clean solution to expose templates to external projects and reduce hpp/cpp duplication.

允许它们一起工作的语法是什么?

What is the syntax that will allow them to work together?

例如,我希望模块看起来像(未经测试,因此可能是错误的代码,因为我的编译器不够新/不确定是否已实施):

For example, I expect modules to look a bit like (untested and therefore likely wrong code because I don't have a compiler new enough/not sure it is implemented yet):

helloworld.cpp

helloworld.cpp

export module helloworld;
import <iostream>;

template<class T>
export void hello(T t) {
    std::cout << t << std::end;
}

helloworld_impl.cpp

helloworld_impl.cpp

export module helloworld_impl;
import helloworld;

// Explicit instantiation
template class hello<int>;

main.cpp

// How to prevent the full definition from being imported here, which would lead
// hello(1) to instantiate a new `hello<int>` instead of reusing the explicit instantiated
// one from `helloworld_impl.cpp`?
import helloworld;

int main() {
    hello(1);
}

,然后在 https://quuxplusone.github.io/blog/2019/11/07/modular-hello-world 将沿用(?)

clang++ -std=c++2a -c helloworld.cpp -Xclang -emit-module-interface -o helloworld.pcm
clang++ -std=c++2a -c -fprebuilt-module-path=. -o helloworld_impl.o helloworld_impl.cpp
clang++ -std=c++2a -fprebuilt-module-path=. -o main.out main.cpp helloworld_impl.o

理想情况下,我也希望模板定义为

Ideally, I also want the template definition to be usable on external projects.

我认为我想要的是一种导入模块的方法,并且在导入时决定在其中一个进行选择:

I think what I want is a way to import the module, and at import time decide between either:


  • 使用模块中的所有模板,就好像它们只是声明一样(我将在另一个文件中提供自己的实例化)

  • 使用模块中的模板就好像它们是定义一样

这基本上是我在C ++ 20之前的版本中在从包含的标头中删除定义,但也将模板公开给外部API ,但是该设置需要将接口复制两次,这看起来像是模块系统基本上可以为我们做。

This is basically what I achieve in pre-C++20 at "Remove definitions from included headers but also expose templates an external API" but that setup requires copying the interfaces twice, which seems like something the module system can essentially do for us.

推荐答案

模块使快速构建案例变得非常容易。他们在支持客户实例化,但避免重建具有明确实例化专长的客户方面做得并不多;从理论上讲,由于避免了重复的工作,构建速度通常更快,因此无需扭曲程序即可节省更多时间。

Modules make the "fast single build" case very easy. They don’t do much for the "support client instantiation but avoid rebuilding clients of the explicitly instantiated specializations" case; the theory is that the generally faster builds from avoiding repeated work makes it unnecessary to contort the program so as to save even more time.

全部您要做的是在模块界面中放置一个明确的实例化定义

All you do is put an explicit instantiation definition in the module interface:

export module A;
export template<class T>
inline void f(T &t) {++t;}
template void f(int&);
template void f(int*&);

导入程序无需实例化 f 即使功能模板是 inline (这可能需要非模块化代码中的其他实例化),这两种类型中的任何一种也是如此。一个典型的实现将那些实例化的结果缓存在编译后的模块接口文件中,并具有足够的详细信息以内联到导入器中(以及将模板本身缓存有足够的详细信息以进一步实例化它)。

Importers will not have to instantiate f for either of those two types, even though the function template is inline (which may require additional instantiations in non-modular code). A typical implementation caches the results of those instantiations in the compiled module interface file with sufficient detail to inline calls in an importer (as well as caching the template itself with sufficient detail to instantiate it further).

您当然也可以使用显式实例化 declaration ,只需在接口中声明模板,然后定义模板并将显式实例化 definitions 放入一个模块实现单元,但这与头文件的工作原理没有什么不同。

You can of course also use an explicit instantiation declaration with just a declaration of the template in the interface and define the template and put explicit instantiation definitions in a module implementation unit, but that’s no different from how header files work.

这篇关于如何在C ++ 20模块中使用模板显式实例化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆