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

时间:2017-09-28 13:04:26

标签: c++ language-lawyer circular-dependency c++-modules

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

a.cpp

module foo.a;

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

import foo.b;
void foo::A::doA() {
     B{}.doB();
}

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

的main.cpp

import foo.b;

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

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

2 个答案:

答案 0 :(得分:2)

来自Working Draft, Extensions to C++ for Modules(见Experimental C++ Features),第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形成 循环接口依赖

答案 1 :(得分:1)

是的,你必须为至少一个模块使用单独的实现文件(概念上是#34;低级&#34;)。 PDTS&#39; s [dcl.module.import] / 3说

  

如果M1的模块接口包含 module-import-declaration <,模块M2在模块M1上具有接口依赖 / em>提名M2。模块不应具有对自身的传递接口依赖性。

无论 module-import-declaration 的位置如何,这都适用,因为export可以在模块接口单元中的任何位置出现多次。该规则旨在防止在另一个模块的接口中出现两个模块中的每个模块的类型和模板,因为这两个模块都不能导入&#34; first&#34;。