![](/img/trans.png)
[英]Forward declaration to break cyclic dependency in C++20 modules doesn't work
[英]C++20 Modules “cyclic dependency”
我試圖在另一個模塊中包含一個模塊,但由於以下錯誤我無法編譯:
“無法構建以下源文件,因為它們之間存在循環依賴關系:Module1.ixx 依賴於 Module2.ixx 依賴於 Module1.ixx。”
我想 modClass1_ 包含 modClass2_ class 和 modClass2_ 包含指向 static modClass1_ 的指針。
我嘗試使用 C++17 Header 和源文件(.h 和.cpp)成功的代碼
// Class1.h
#pragma once
#include "Class2.h"
class modClass2_;
class modClass1_
{
public:
modClass1_() {};
~modClass1_() {};
int V = 2;
int getV() { return V; };
static modClass2_ mc2;
};
extern modClass1_ mc1;
// Class1.cpp
#include "Class1.h"
modClass1_ mc1;
modClass2_ modClass1_::mc2;
// Class2.h
#pragma once
#include "Class1.h"
class modClass2_
{
public:
modClass2_() {};
~modClass2_() {};
int V = 1;
int getV() { return V; };
int getClass1V();
};
// Class2.cpp
#include "Class2.h"
int modClass2_::getClass1V()
{
return mc1.V;
}
// Main.cpp
#include "Class1.h"
#include <iostream>
int main()
{
std::cout << mc1.getV() << "\n"; // gets modClass1_ V directly
std::cout << mc1.mc2.getClass1V() << "\n"; // gets modClass1_ V through modClass2_ through modClass1_
std::cout << mc1.mc2.getV() << "\n"; // gets modClass2_ V through modClass1_
}
我嘗試過但使用 C++20 模塊 (.ixx) 失敗的代碼
// Module1.ixx
export module Module1;
import Module2;
export class modClass1_
{
public:
modClass1_() {};
~modClass1_() {};
int getV() { return V; };
modClass2_ mc2;
int getModule2V() { return mc2.V; };
int V = 1;
};
export modClass1_ mc1;
// Module2.ixx
export module Module2;
import Module1;
export class modClass2_
{
public:
modClass2_() {};
~modClass2_() {};
int getV() { return V; };
int getModule1V() { return mc1.V; };
int V = 2;
};
任何幫助/建議將不勝感激。
環境:Visual Studio 2019 | MSVC-2019 | C++20 | Windows 10 臨
就像頭文件一樣,您可以將模塊接口文件與模塊實現文件分開。 例子:
模塊1.ix:
export module Module1;
import Module2;
export class modClass1_
{
public:
modClass1_() {};
~modClass1_() {};
int getV() { return V; };
modClass2_ mc2;
int getModule2V() { return mc2.V; };
int V = 1;
};
export modClass1_ mc1;
模塊2.ix:
export module Module2;
export class modClass2_
{
public:
modClass2_() {};
~modClass2_() {};
int getV() { return V; };
int getModule1V();
int V = 2;
};
模塊2.cpp:
import Module1;
import Module2;
int modClass2_::getModule1V()
{
return mc1.V;
}
主.cpp:
#include <iostream>
import Module1;
import Module2;
int main()
{
// NB: mc1 is a symbol imported from Module1
std::cout << "mc1.V: " << mc1.V << '\n';
std::cout << "mc1.getModule2V: " << mc1.getModule2V() << '\n';
modClass2_ mc2;
std::cout << "mc2.V: " << mc2.V << '\n';
std::cout << "mc2.getModule1V: " << mc2.getModule1V() << '\n';
}
請注意, modClass2_
的接口不需要來自Module1
任何內容,因此Module2.ixx
沒有import Module1;
. 實現所在的Module2.cpp
確實如此。
在我的示例中,我盡可能少地從Module2.ixx
到Module2.cpp
實現文件中,但實際上您可能希望將更多內容移出接口。
我將一個樹數據結構拆分為兩個需要相互引用的模塊,並發布了如何使其工作的答案。 復制粘貼它,這是通過使用模板打破循環依賴的絕望解決方案:
// A_impl.cc
export module A_impl;
export template <typename B> class A_impl {
public:
void f(B& b) {}
};
// B.cc
export module B;
import A_impl;
export class B;
typedef A_impl<B> A;
export class B {
public:
void f(A& a) {}
};
// A.cc
export module A;
export import A_impl;
import B;
export typedef A_impl<B> A;
// main.cc
import A;
import B;
int main(void) {
A a;
B b;
a.f(b);
b.f(a);
return 0;
}
目前,clang 不支持模塊分區,因此使用該工具鏈,這似乎是將 A 和 B 放置在模塊中時在不同文件中定義 A 和 B 的唯一方法(沒有#include
)。 使用 Visual Studio 模塊分區可能允許也可能不允許更清晰的結構。
經gcc測試,模塊分區可以解決使用前向聲明和內部模塊鏈接的問題。 注意:這不會將模塊設置為相互依賴,整個循環依賴項都定義在單個模塊中。
// A.cc
export module Cyclic:A;
export class B;
export class A {
public:
char name() { return 'A'; }
void f(B& b);
};
// B.cc
export module Cyclic:B;
export class A;
export class B {
public:
char name() { return 'B'; }
void f(A& a);
};
// A_impl.cc
module Cyclic:A_impl;
import Cyclic:A;
import Cyclic:B;
import <iostream>;
void A::f(B& b) {
std::cout << name() << " calling " << b.name() << std::endl;
}
// B_impl.cc
module Cyclic:B_impl;
import Cyclic:B;
import Cyclic:A;
import <iostream>;
void B::f(A& a) {
std::cout << name() << " calling " << a.name() << std::endl;
}
// Cyclic.cc
export module Cyclic;
export import :A;
export import :B;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.