标签: c++-modules

我应该如何编写C++来为C++模块做好准备?

已经有两个支持C++模块的编译器:

现在开始一个新项目时,为了能够在我的编译器最终发布时采用模块功能,我应该注意什么?

是否可以使用模块并仍然保持与不支持它的旧编译器的兼容性?

c++ backwards-compatibility future-proof c++20 c++-modules

54
推荐指数
2
解决办法
2万
查看次数

如何在Clang中使用C++模块?

模块是#includes的替代品.Clang有一个完整的C++实现.如果我现在想使用Clang使用模块,我该怎么办?


运用

import std.io;
Run Code Online (Sandbox Code Playgroud)

在C++源文件中还没有工作(编译),因为模块的规范(包括语法)不是最终的.


锵文件指出,经过时-fmodules标志,#包括将被改写到相应的进口.但是,检查预处理器会另外建议(test.cpp只包含#include <stdio.h>一个空的main):

$ clang++-3.5 -fmodules -E test.cpp -o test
$ grep " printf " test
extern int printf (const char *__restrict __format, ...);
Run Code Online (Sandbox Code Playgroud)

此外,使用-fmodulesvs no flags 编译此测试文件会产生相同的目标文件.

我究竟做错了什么?

c++ clang c++20 c++-modules

33
推荐指数
2
解决办法
1万
查看次数

如何在C++模块系统中处理模板?

我正在阅读论文A Module System for C++ 来理解C++模块,这是C++的一个提议特性.

我无法完全理解此模块架构如何导出模板.

有任何想法吗?

c++ c++20 c++-modules

29
推荐指数
1
解决办法
4256
查看次数

模块接口中的内联含义

考虑头文件:

class T
{
private:
  int const ID;

public:
  explicit T(int const ID_) noexcept : ID(ID_) {}

  int GetID() const noexcept { return ID; }
};
Run Code Online (Sandbox Code Playgroud)

或者,或者:

class T
{
private:
  int const ID;

public:
  explicit T(int const ID_) noexcept;

  int GetID() const noexcept;
};

inline T::T(int const ID_) noexcept : ID(ID_) {}

inline int T::GetID() const noexcept { return ID; }
Run Code Online (Sandbox Code Playgroud)

在预模块世界中,这些标头可能会以文本形式包含在多个 TU 中,而不会违反 ODR。此外,由于涉及的成员函数相对较小,编译器可能会“内联”(在使用时避免函数调用)这些函数,甚至优化掉一些实例T

在最近关于 C++20 完成会议的报告中,我可以阅读以下声明:

我们澄清了inline模块接口中的含义:意图是未明确声明的函数体不是inline模块 ABI 的一部分,即使这些函数体出现在模块接口中。为了让模块作者更好地控制他们的 …

c++ language-lawyer c++20 c++-modules

26
推荐指数
2
解决办法
966
查看次数

C++ 模块中命名空间内的“using”不限于命名空间

给定以下模块example

module;

#include "example.h" // `namespace cxx { struct example {}; }`

export module example;

export namespace cxx::containers
{
    using cxx::example;
}
Run Code Online (Sandbox Code Playgroud)

cxx::containers::examplecxx::example也可以从我只希望cxx::containers::example出现的地方访问。

import example;

int main()
{
    auto v1 = cxx::containers::example();
    auto v2 = cxx::example();
}
Run Code Online (Sandbox Code Playgroud)

cxx::example即使我只在命名空间内使用它cxx::containers::example并且#include全局module;片段中的指令应该本地化到它们的模块,但它仍然可见的原因是什么?

c++ c++20 c++-modules

18
推荐指数
1
解决办法
985
查看次数

导出命名空间后的所有内容都未导出吗?

我正在阅读有关模块的内容,我希望这样做:

a.cpp

module foo.a;

export namespace foo {
    struct A {
        void doA();
    };
}

import foo.b;
void foo::A::doA() {
     B{}.doB();
}
Run Code Online (Sandbox Code Playgroud)

b.cpp

module foo.b;

export namespace foo {
    struct B {
        void doB();
        void start();
    };
}

import foo.a;
import std.io;
void foo::B::doB() {
     std::cout << "Stuff done!" << std::endl;
}

void foo::B::start() {
     A{}.doA();
}
Run Code Online (Sandbox Code Playgroud)

main.cpp中

import foo.b;

int main() {
    foo::B{}.start();
}
Run Code Online (Sandbox Code Playgroud)

由于模块接口不能互相使用,为了使其工作,导出的命名空间之后的所有内容都不能成为接口的一部分.根据目前的TS,上述是否正确?对于实现中的循环依赖,是否需要将其拆分为另一个文件?

c++ circular-dependency language-lawyer c++-modules

16
推荐指数
1
解决办法
919
查看次数

什么是C++模块权限?

我在C++模块的上下文中看到了一些对"purview"这个术语的引用,例如在https://gcc.gnu.org/wiki/cxx-modules中:

Baz (); // Baz's declaration visible from purview Quux interface
Run Code Online (Sandbox Code Playgroud)

究竟什么是C++模块权限?

c++ terminology c++-modules

16
推荐指数
1
解决办法
1020
查看次数

C++20 模块会改变静态库和共享库的结构吗?

传统上,C++ 库由一个头文件 + 编译成二进制文件(.a, .so, .dylib, .dll, ...)的实现组成。头文件#include在源代码中是d,二进制部分链接到最终的可执行文件。

C++20 的模块会改变这种布局吗?如果是这样,操作系统是否必须升级它们分发核心库的方式,例如 Linux 中的标准库或 Windows 中的其他核心 dll?

c++ c++20 c++-modules

16
推荐指数
1
解决办法
508
查看次数

使用C++模块时,是否有任何理由将函数声明(.hpp文件)与其定义(.cpp文件)分开?

我习惯于编写没有模块的代码,其中头文件包含函数声明,如:

// foo.h 
class Foo
{
    void bar();
};
Run Code Online (Sandbox Code Playgroud)

并且相应的.cpp文件包含以下定义:

// foo.cpp
#include "foo.h"

void Foo::bar()
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

据我所知,这样做是为了减少编译时间并减少依赖性.当使用模块时,这仍然适用吗?将类放在单个文件中的定义与Java和C#的定义方式一样快吗?如果是这种情况,使用模块时是否需要.hpp.cpp文件?

c++ c++20 c++-modules

14
推荐指数
2
解决办法
1614
查看次数

模块接口/实现单元和分区的正交性

C++20 标准似乎定义了模块单元的两类:接口/实现单元,以及模块单元是否是分区。这两个分类看起来是正交的:您可以拥有一个是分区的实现单元、一个不是分区的接口单元,等等。

分类的接口/实现轴似乎是关于你能做什么import和不能做什么。但如果这是真的,那么作为命名分区的实现单元有什么意义呢?难道你不能让这个实现单元不是一个分区吗?

这两个概念真的是正交的,还是有些相互依赖的?如果是后者,他们之间的依赖程度如何?

c++ c++20 c++-modules

14
推荐指数
1
解决办法
747
查看次数