我想创建包含这样相同的结构的列表的结构:

#include <list>
struct Url
{
    CString strUrl;
    std::list<Url> children;
};

int main()
{
    Url u1, u2;
    u1.children.push_back(u2);
}

此代码不被编译。但是,当我与std::list取代std::vector它工作正常。我怎样才能让这个与std::list工作?

输出窗口包含以下错误。

c:\program files\microsoft visual studio\vc98\include\list(29) : error C2079: '_Value' uses undefined struct 'Url'
        E:\test\Test.cpp(23) : see reference to class template instantiation 'std::list<struct Url,class std::allocator<struct Url> >' being compiled
c:\program files\microsoft visual studio\vc98\include\functional(185) : error C2079: 'value' uses undefined struct 'Url'
        c:\program files\microsoft visual studio\vc98\include\list(285) : see reference to class template instantiation 'std::binder2nd<struct std::not_equal_to<struct Url> >' being compiled
        E:\test\Test.cpp(23) : see reference to class template instantiation 'std::list<struct Url,class std::allocator<struct Url> >' being compiled
有帮助吗?

解决方案

如果你需要什么似乎是一个错误VC6一个workround,动态创建列表:

#include <list>
#include <string>     // I don't use MFC

struct Url
{
    std::string strUrl;
    std::list<Url> * children;

    Url() {
       children = new std::list <Url>;
    }

    ~Url() {
        delete children;
    }
};

int  main()
{
    Url u1, u2;
    u1.children->push_back(u2);
}

一些问为什么相同类型成员的列表被允许(在我视图它们是)时

Url array[5]; 

例如作为构件不会。我找不到在标准或者什么,但sizeof( std:;list <T>)是不依赖于东西它是一个列表。假设清单实现为(一些伪C ++这里):

list <T> {
   listEntry <T> * first;
};

那么就没有未知大小来处理。考虑下面的最少的代码,解决所述问题的提问:

template <typename T> struct A {
};

struct B {
    A <B> b;
};

我看不到任何可能的原因,这不应该是合法的。

其他提示

你能告诉我们你所使用的编译器?没有什么内在的错误,你在做什么。我尝试以下上VS2008 SP1和它已编译没有问题

#include <list>

struct Url
{
    std::string name;
    std::list<Url> children;
};

int _tmain(int argc, _TCHAR* argv[])
{
    Url u1,u2;
    u1.children.push_back(u2);
    return 0;
}

你也许忘了,包括列表?

修改

OP是使用Visual Studio 6.0和尼尔得以确认它的确是在VS6的错误

相反在其他的答案的权利要求,这的确是的法律来实例化的任何标准容器,包括std::list,具有一个不完整的类型。 (对于讨论此,参见例如如何一个不完整的类型被用作模板参数这里向量?

这要求在C ++ 17 std::forward_liststd::liststd::vector仅被放宽。对于任何早期标准,原代码用VC和gcc的新版本的工作是一个非标准扩展。这也适用于与std::vector您的意见。

在预C ++ 17,可移植有一些类std::list作为所述类的构件的T,你需要像std::list<T*>一种变通方法或使用boost.container库,它已经便携实现了宽松的要求。

请注意,即使在C ++ 17,可能只实例化的类模板本身具有一个不完整的类型。类型仍然必须是完整的,当任何部件被实例化。

有趣的 - 你要创建不完全类型的vectorlist。从快速看一下标准,我找不到任何东西说这是否是或不应该被允许包含在C ++标准库中的容器类型。任一判决似乎是合理的:

<强>为什么它可能不允许:您不能声明类型X的目的X的定义内

E.g。下面的代码编译失败,因为它会造成一个无限深数据结构:

struct X {
    X x;
};

<强>为什么它可能被允许大多数容器是可调整大小的,因此需要一个间接层(指针)在实践中的实际数据元素。是合法的声明X的定义内的指针到X

随着最后一段表明,通常的方式来解决这个问题是使用指针或引用X。例如。下面的两个片段编译就好:

struct Y {
    Y* y;
};

struct Z {
    std::list<Z*> zl;
    std::vector<Z*> zv;
};

任何人(好吧,我的意思是litb :-P)是否知道有什么要求,其实是标准的容器类型?

代码编译非常清楚与GCC 4.4 和完美的执行。 MSVC ++前7版本,是不是完全符合标准。你应该考虑使用较新的编译器。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top