【赤石C++】使用模版二阶段名称查找解决循环依赖问题
· 阅读需 3 分钟
最近在知乎上看到的, 发现挺神奇的, 就仔细看看. 突发奇想, 如果是普通类, 是不是可以使用几个宏, 封装一下, 这样就变成模版.
这样可以使用模版二阶段名称查找, 从而解决循环依赖问题?
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() {}
};
此时我们可以套一个模版:
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;
}
以上~, 当然你可以整个宏, 但是大可不必, 也太丑了吧! 有这个时间还不如重构呢!
拓展的、系统学习一下: