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óduloM2
si la interfaz de módulo deM1
contiene un móduloM2
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óduloM2
si la interfaz de módulo deM1
contiene un móduloM2
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".