【问题标题】:Interdependent class templates design?相互依赖的类模板设计?
【发布时间】:2013-05-29 04:41:20
【问题描述】:

考虑以下设计:

template <class SecondType>
struct First
{
    SecondType* _ptr;
};

template <class FirstType>
struct Second
{
    FirstType* _ptr;
};

First 类型有一个指向Second 类型的指针,反之亦然。问题是我不能声明它,因为它们是相互依赖的,我应该声明First&lt;Second&lt;First&lt;Second...&gt;&gt;&gt;

如何解决这个问题?

【问题讨论】:

  • 这究竟是在模仿什么?
  • 为什么要设计上面的类?你想解决什么现实生活中的问题?

标签: c++ class templates c++11


【解决方案1】:

也许可以解决看起来像 CRTP 但更疯狂的东西:

#include <iostream>

template <class SecondType>
struct FirstBase
{
    SecondType* _ptr;
};

template <class FirstType>
struct SecondBase
{
    FirstType* _ptr;
};

struct FirstDerived
: public FirstBase<SecondBase<FirstDerived>>
{
};

struct SecondDerived
: public SecondBase<FirstBase<SecondDerived>>
{
};

int main()
{
    FirstBase<SecondDerived> x;
    SecondBase<FirstDerived> y;
    return 0;
}

如果有人有更优雅的方式来做到这一点,我会很高兴看到它。

【讨论】:

  • 我假设您不希望我们过多地更改模板,因为没有模板会很容易
【解决方案2】:

不确定您要实现什么,但以下编译正常。

template <class T> struct First  { T* _ptr; };
template <class T> struct Second { T* _ptr; };

int main(){
   First<Second<First<Second<void>>>> a; // or
   First<Second<First<Second<nullptr_t>>>> b;
   return 0;
}

注意,我完全替换了 FirstType,SecondType 因为没关系。 T 将被您传递的任何内容替换,这将在编译之前专门化模板时发生。

【讨论】:

    【解决方案3】:

    这是另一个可能更优雅的解决方案,它根本不需要 void。我不知道您是否可以接受继承,但我认为它运作良好。

    #include<vector>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    struct Base {
        //make all functions virtual
    };
    template <class SecondType>
    struct First: public Base
    {
        SecondType* _ptr;
        First(SecondType * st) {
            _ptr = st;
        }
        First() {
        }
    };
    
    template <class FirstType>
    struct Second: public Base
    {
        FirstType* _ptr;
        Second(FirstType * ft) {
            _ptr = ft;
        }
        Second() {
        }
    };
    
    int main() {
        First<Base> f;
        Second<Base>  s;
        f._ptr = &s;
        s._ptr = &f;
        cout << s._ptr << endl;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-25
      • 2013-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多