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

c++ - ¿No se exporta todo después de un espacio de nombres de exportación?



language-lawyer circular-dependency (2)

Del Borrador de Trabajo, Extensiones a C ++ para Módulos (que se encuentran en las en.cppreference.com/w/cpp/experimental ), página 13, §10.7.2: 3:

Un módulo M1 tiene una dependencia de interfaz con respecto a un módulo M2 si la interfaz de módulo de M1 contiene un módulo M2 designa una declaración de importación. Un módulo no debe tener una dependencia de interfaz transitiva sobre sí mismo.

Ejemplo:

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

P: "Para la dependencia circular en la implementación, ¿es necesario dividirla en otro archivo?"

A: si

P: "¿Es correcto lo anterior de acuerdo con el TS actual?"

A: No.

En su código, tiene un error, ya que foo.a y foo.b forman una dependencia de interfaz cíclica .

Estaba leyendo sobre módulos, y deseaba hacer algo como esto:

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

Como las interfaces de los módulos no pueden usarse entre sí, para que funcione, todo lo que esté después del espacio de nombres exportado no debe formar parte de la interfaz. ¿Es correcto lo anterior de acuerdo con el TS actual? Para la dependencia circular en la implementación, ¿es necesario dividirla en otro archivo?


Sí, tiene que usar un archivo de implementación separado para al menos uno de los módulos (el que es conceptualmente de "nivel inferior"). El [dcl.module.import] / 3 del PDTS dice

Un módulo M1 tiene una dependencia de interfaz con respecto a un módulo M2 si la interfaz de módulo de M1 contiene un módulo M2 designa una declaración de importación . Un módulo no debe tener una dependencia de interfaz transitiva sobre sí mismo.

Esto se aplica independientemente de la ubicación de la declaración de importación de módulo , ya que la export puede aparecer en cualquier lugar y varias veces en una unidad de interfaz de módulo. El objetivo de la regla es evitar la aparición de tipos y plantillas de cada uno de los dos módulos en la interfaz del otro, ya que ninguno de ellos podría importarse "primero".