16

我正在阅读有关模块的内容,并且希望执行以下操作:

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

主文件

import foo.b;

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

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

4

2 回答 2

2

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

如果模块接口包含 module-import-declaration 提名,则模块对模块M1具有接口依赖关系。一个模块不得对自身有传递接口依赖。M2M1M2

例子:

// 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

Q:“对于实现中的循环依赖,是否需要拆分成另一个文件?”

答:是的。


Q:“根据目前的TS,以上正确吗?”

答:没有。

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

于 2017-10-10T14:10:04.223 回答
1

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

如果模块接口包含module-import-declaration nominating ,则模块对模块M1具有接口依赖关系。一个模块不得对自身有传递接口依赖。M2M1M2

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

于 2017-10-06T19:21:53.533 回答