题
我想创建包含这样相同的结构的列表的结构:
#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_list
,std::list
和std::vector
仅被放宽。对于任何早期标准,原代码用VC和gcc的新版本的工作是一个非标准扩展。这也适用于与std::vector
您的意见。
在预C ++ 17,可移植有一些类std::list
作为所述类的构件的T
,你需要像std::list<T*>
一种变通方法或使用boost.container库,它已经便携实现了宽松的要求。
请注意,即使在C ++ 17,可能只实例化的类模板本身具有一个不完整的类型。类型仍然必须是完整的,当任何部件被实例化。
有趣的 - 你要创建不完全类型的vector
或list
。从快速看一下标准,我找不到任何东西说这是否是或不应该被允许包含在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版本,是不是完全符合标准。你应该考虑使用较新的编译器。