跳到主要内容
左猫娘右猫娘

【赤石C++】使用模版二阶段名称查找解决循环依赖问题

· 阅读需 3 分钟
Heng_Xin
ここから先は一方通行だ!

最近在知乎上看到的, 发现挺神奇的, 就仔细看看. 突发奇想, 如果是普通类, 是不是可以使用几个宏, 封装一下, 这样就变成模版.

这样可以使用模版二阶段名称查找, 从而解决循环依赖问题?

Tip

本节是赤石C++!, 不建议实际使用!

咱们先看看什么是循环依赖吧~

考虑以下代码, 有时候我们可能需要注入一个类到另一个类内部, 但是双方都有其引用, 可以直接调用.

为什么会写这种垃圾代码? 因为架构没想好或者突然来需求, 然后其他又没法重构了憋...

struct B;

struct A {
explicit A(B& b)
: _b(b)
{}

void func() {
_b.todo(); // ERROR: Member access into incomplete type 'B'
}

B& _b;
};

struct B {
A& a;

void todo() {}
};
cpp

此时我们可以套一个模版:

template <typename T>
struct B;

template <typename T = void>
struct A {
static_assert(std::is_same_v<T, void>, "error"); // 可以加个这个, 来限制类型~

explicit A(B<T>& b)
: _b(b)
{}

void fun() {
_b.todo(*this); // 可以使用 _b !
}

B<T>& _b;
};

template <typename T = void>
struct B {
void todo(A<T>& a) {
static_cast<void>(a._b); // 此处只是演示真的可以调用 a 的_b,
// 不转void在我这里就是警告, 就是编译错误 (cmake设置了)
HX::print::println("todo: B");
}
};

int main() {
// 因为模版默认参数的存在, 用户可能根本不知道这里有个模版! 还以为是普通类呢~
B b{};
A a{b};
a.fun();
return 0;
}
cpp

以上~, 当然你可以整个宏, 但是大可不必, 也太丑了吧! 有这个时间还不如重构呢!

拓展的、系统学习一下:

请作者喝奶茶:
Alipay IconQR Code
Alipay IconQR Code
本文遵循 CC CC 4.0 BY-SA 版权协议, 转载请标明出处
Loading Comments...