gpt4 book ai didi

C++:当两个类包含指向另一个类的指针时,如何解决派生类之间的模板循环依赖?

转载 作者:行者123 更新时间:2023-12-02 07:32:20 26 4
gpt4 key购买 nike

我有一个父类和一些从它派生的类。我想将两个派生类“配对”,eac 有一个指向另一个派生类的指针。

代码示例:

template<typename DerivedClassName>
class Parent {
// some stuff
DerivedClassName* prtToPair;
};

template<typename DerivedClassName>
class DerivedA : public Parent<DerivedClassName> {

};


template<typename DerivedClassName>
class DerivedB : public Parent<DerivedClassName> {

};

// compile fails
DerivedA<DerivedB> dA;
DerivedB<DerivedA> dB;

dA.prtToPair = &dB;
dB.prtToPair = &dA;

我知道我可以使用虚函数来做到这一点,但我尝试找到一种使用模板的方法。

我从 http://qscribble.blogspot.com/2008/06/circular-template-references-in-c.html 找到了解决方案:

#include <stdio.h>

template<class Combo> struct A
{
typedef typename Combo::b_t B;
B* b;
};

template<class Combo> struct B
{
typedef typename Combo::a_t A;
A* a;
};

struct MyCombo {
typedef A<MyCombo> a_t;
typedef B<MyCombo> b_t;
};

int main(int argc, char* argv[])
{
A<MyCombo> a;
B<MyCombo> b;
a.b = &b;
b.a = &a;
return 0;
}

但它只适用于两个固定类 A 和 B。考虑到我有很多派生类,并且我想将它们中的任意两个“配对”,我该如何解决这个问题?

更新1.修复第一个代码块中的拼写错误更新2.我尝试了以下代码

template<typename DerivedClassName>
class Parent {
// some stuff
public:
DerivedClassName *prtToPair;
};

template<typename DerivedClassName>
class DerivedA : public Parent<DerivedClassName> {
public:
void func() {
std::cout << "A" << std::endl;
}
};


template<typename DerivedClassName>
class DerivedB : public Parent<DerivedClassName> {
public:
void func() {
std::cout << "B" << std::endl;
}
};

int main() {
DerivedA<DerivedB<void>> A;
DerivedB<DerivedA<void>> B;

A.prtToPair = reinterpret_cast<DerivedB<void> *>(&B);
B.prtToPair = reinterpret_cast<DerivedA<void> *>(&A);

A.prtToPair->func();
B.prtToPair->func();

return 0;
}

它编译并打印了B A。但这段代码正确吗?有没有副作用?

最佳答案

类似于下面的内容?

#include <type_traits>

template <typename Combo>
struct Parent {
// some stuff
typename Combo::other_type* prtToPair;
};

template <typename Combo>
class DerivedA : public Parent<Combo> {};

template <typename Combo>
class DerivedB : public Parent<Combo> {};

template <template <typename...> class T, template <typename...> class U>
struct Combo {
private:
template <typename Combo, bool B>
struct impl {
using other_type =
typename std::conditional_t<B, typename Combo::type2, typename Combo::type1>;
};

public:
using type1 = T<impl<Combo, true>>;
using type2 = U<impl<Combo, false>>;
};

int main() {
using C = Combo<DerivedA, DerivedB>;
using A = typename C::type1;
using B = typename C::type2;

A dA;
B dB;

dA.prtToPair = &dB;
dB.prtToPair = &dA;
}

这使得这两种类型依赖于 Combo它们与正确的other_type相关联并进行选择是 Combo 实现的一部分。请注意Combo<DerivedA, DerivedB>Combo<DerivedB, DerivedA>不过,现在会导致不同的类型。

<小时/>

关于您的编辑:

通过 reinterpret_cast 返回的指针访问值到不相关的类型或使用它调用非静态成员函数(正如您所做的那样)会导致未定义的行为。

关于C++:当两个类包含指向另一个类的指针时,如何解决派生类之间的模板循环依赖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59341379/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com