是否可以C++递归类型定义,特别是我可以在 T 的定义中放置一个向量<T>吗?
Are C++ recursive type definitions possible, in particular can I put a vector<T> within the definition of T?
对于我的一个项目,我真正想做的是这样(将其简化到最低限度);
struct Move
{
int src;
int dst;
};
struct MoveTree
{
Move move;
std::vector<MoveTree> variation;
};
我必须承认,我认为不可能直接做到这一点,我认为MoveTree中的MoveTree向量会被禁止。但我还是试过了,效果很好。我正在使用Microsoft Visual Studio 2010学习版。
这是便携式的吗?这是好的练习吗?我有什么要担心的吗?
编辑:我问了第二个问题,希望能找到一个好的方法。
C++标准(2003)明确指出,实例化具有不完整类型的标准容器会调用未定义的行为。
规范在§17.4.3.6/2 中规定
特别是,在以下情况下,影响是不明确的:
__[..]
--如果在实例化模板组件时使用不完整类型(3.9)作为模板参数
__[..]
随着C++17标准的出现,情况发生了变化,该标准明确允许std::list
、std::vector
和std::forward_list
进行这种类型的递归。有关参考,请参见http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4510.html答案是:如何声明同一类的成员向量?
MoveTree
在其定义中是一个不完整的类型。该标准不保证具有不完整类型的STL模板的实例化。
使用指向Vector中类型的指针,这将是可移植的。
struct Move
{
int src;
int dst;
};
struct MoveTree;
struct MoveTree
{
Move move;
std::vector<MoveTree*> variation;
};
std::vector
中的MoveTree
元素位于已分配的(如new []
中)数组中。只有控制信息(指向数组的指针、大小等)存储在MoveTree
内的std::vector
内。
不,它不可移植。codepad.org不编译它。
t.cpp:14: instantiated from here
Line 215: error: '__gnu_cxx::_SGIAssignableConcept<_Tp>::__a' has incomplete type
compilation terminated due to -Wfatal-errors.
使用vector时,应为Move
和MoveTree
定义复制构造函数和赋值运算符,否则将使用编译器生成的,这可能会导致问题。
- 用C++中的一个变量定义一个常量
- 在类定义之后定义一个私有方法
- 如何定义一个纯抽象基类
- 为什么我不能在主函数之外定义一个类的对象(它继承了另一个类)?
- 如何定义一个没有重复代码的继承的 const 类成员函数?
- 如何在 c++ 中定义一个将被另一个短语替换的短语?
- 是否可以定义一个以向量<T>作为值的unordered_map?
- 我可以定义一个 constexpr 匿名/未命名变量吗?
- 定义一个 void f(void) 函数,但使用来自同一范围的变量?
- 如何在一个函数中定义一个变量,并在另一个函数中访问和更改它?(C++)
- 为什么不建议使用宏符号常量定义一个固定长度的数组呢
- 在C++中,我想通过使用来自变量(例如字符串)的typename信息,从模板中定义一个类对象
- 为什么我必须显式定义一个由固有类提供的方法
- 定义一个带有缓冲区的函数作为卤化物中的边界框参数
- Visual Studio 2017 C++,如何定义一个"环境变量"'Additional Library Directory'?
- 如何键入定义一个专门的 std::set 模板,使用特定的比较函数实例化
- 仅使用 bool 和 char 定义一个 templete 类
- 定义一个工厂函数,该函数返回指向在此工厂函数中创建的函数的指针
- 是否可以定义一个非模板函数,该函数可以将模板化对象作为参数
- 如何在C 中定义一个副操作员