具有完整类型信息的循环依赖

时间:2015-01-21 14:52:57

标签: c++ templates

我有两个类,它们都包含在变体中。然后在两个类中使用该变体。

template <typename T>
struct Deferred
{
    typedef T value_type;
};

template <typename T>
struct DeferredContainer
{
    typedef typename T::value_type value_type;
};

class DictionaryObject;
class MixedArrayObject;

using DictionaryObjectPtr = Deferred < DictionaryObject >; // DeferredContainer<DictionaryObject>
using MixedArrayObjectPtr = Deferred < MixedArrayObject >; // DeferredContainer<MixedArrayObject>

typedef boost::variant <
    MixedArrayObjectPtr,
    DictionaryObjectPtr
> ContainerPtr;

class MixedArrayObject
{
public:
    typedef int value_type;

    inline void SetContainer(ContainerPtr obj) { _container = obj; }
    inline ContainerPtr GetContainer() const { return _container; }

private:
    ContainerPtr _container;
};

class DictionaryObject
{
public:
    typedef float value_type;

    inline void SetContainer(ContainerPtr obj) { _container = obj; }
    inline ContainerPtr GetContainer() const { return _container; }

private:
    ContainerPtr _container;
};

我不确切知道它是如何工作的,但当我尝试通过typedef在数组或字典上公开某些属性(并在DeferredContainer中使用它们)时,我收到错误:

  

错误C2602:'DeferredContainer :: value_type'不是'DeferredContainer'基类的成员

我能以某种方式完成这项工作吗?还有其他想法吗?


更新31.5,下午4:09。

我已将问题减少到最低限度。希望这最终得到关注。 code

将MixedArrayObjectPtr切换为DeferredContainer后,代码将不再编译。

1 个答案:

答案 0 :(得分:3)

我建议您重新排序代码,以确保所有定义都按其使用顺序排列。由于需要,我们必须使用Object*代替Object variant有完整的类型:

// main types
class Dictionary;
class Array;
template <typename T> struct DeferredContainer;

using DictionaryPtr = DeferredContainer<Dictionary>;
using ArrayPtr = DeferredContainer<Array>;

struct Object;

// now definitions of them
class Dictionary
{
public:
     typedef int value_type;
     std::map<Name, Object*> list; // note Object*
};

class Array
{
public:
     typedef int value_type;
     std::vector<Object*> list; // note only one type here
};

template <typename T>
struct DeferredContainer
{
    // now can do stuff with T::value_type
};

毕竟,我们可以声明Object。不幸的是,我们无法转发声明别名,但我们可以结束variant

struct Object {
    boost::variant<
        DictionaryPtr,
        ArrayPtr
    > value;
};

通过这种排序,一切都可以编译。