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

Is everything after an exporting namespace not exported?

本文关键字:命名空间      更新时间:2023-10-16

我正在阅读有关模块的信息,我希望做这样的事情:

答.cpp

module foo.a;
export namespace foo {
struct A {
void doA();
};
}
import foo.b;
void foo::A::doA() {
B{}.doB();
}

乙.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();
}

主.cpp

import foo.b;
int main() {
foo::B{}.start();
}

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

来自工作草案,对C++的扩展 模块(可在实验C++功能中找到),第 13 页,§10.7.2:3:

模块M1对模块具有接口依赖性M2如果模块M1的接口包含一个模块-导入-声明提名M2。一个 模块不应具有对自身的传递接口依赖关系。

例:

// Interface unit of M1
export module M1;
import M2;
export struct A { };
// Interface unit of M2
export module M2;
import M3;
// Interface unit of M3
export module M3;
import M1; // error: cyclic interface dependency M3 -> M1 -> M2 -> M3

问:"对于实现中的循环依赖关系,是否需要将其拆分到另一个文件中?

答:是的。


问:"根据当前的TS,上述内容是否正确?

答:没有。

在代码中,您有一个错误,因为foo.afoo.b形成循环接口依赖项

是的,您必须为至少一个模块(概念上是"较低级别"的模块)使用单独的实现文件。 PDTS的[dcl.module.import]/3说

如果模块M1M1的模块接口包含模块导入声明提名M2,则模块对模块M2具有接口依赖关系。模块不应具有对自身的传递接口依赖关系。

无论模块导入声明的位置如何,这都适用,因为export可以在模块接口单元中的任何位置多次出现。 该规则旨在防止两个模块中的每一个的类型和模板出现在另一个模块的界面中,因为这样两者都不能"首先"导入。