Все ли после экспорта пространства имен не экспортируется?

Я читал о модулях, и я хотел сделать что-то вроде этого:

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? Для циклической зависимости в реализации требуется ли разбить ее на другой файл?

Ответы

Ответ 1

Из рабочий проект, расширения для С++ для Модули (найдено в Экспериментальные возможности С++), стр. 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

Q: "Для циклической зависимости в реализации требуется ли разбить ее на другой файл?"

A: Да.


Q: "Правильно ли это указано в соответствии с текущим TS?"

A: Нет.

В вашем коде у вас есть ошибка, так как foo.a и foo.b формируют зависимость от циклического интерфейса.

Ответ 2

Да, вы должны использовать отдельный файл реализации для хотя бы одного из модулей (концептуально "нижнего уровня" ). PDTS [dcl.module.import]/3 говорит

Модуль M1 имеет зависимость интерфейса от модуля M2, если интерфейс модуля M1 содержит декларацию объявления модуля-импорта M2. Модуль не должен иметь переходную зависимость интерфейса от себя.

Это применяется независимо от местоположения модуля-импорта-декларации, поскольку export может появляться где угодно и несколько раз в модуле интерфейса модуля. Это правило предназначено для предотвращения появления типов и шаблонов из каждого из двух модулей в интерфейсе другого, так как тогда ни один из них не может быть импортирован "первым".