Подтвердить что ты не робот

Возможны ли определения рекурсивного типа С++, в частности, можно ли положить вектор <T> в определение T?

Для одного из моих проектов я действительно хотел сделать это (упрощая его до минимума);

struct Move
{
    int src;
    int dst;
};

struct MoveTree
{
    Move move;
    std::vector<MoveTree> variation;
};

Я должен признать, что я предположил, что это будет невозможно сделать прямо, я думал, что вектор MoveTree s внутри MoveTree будет verboten. Но я все равно попробовал, и он прекрасно работает. Я использую Microsoft Visual Studio 2010 Express.

Является ли это переносной? Это хорошая практика? Мне о чем беспокоиться?

Изменить: я попросил второй question надеясь найти хороший способ сделать это.

4b9b3361

Ответ 1

В стандарте С++ (2003) четко сказано, что создание экземпляра стандартного контейнера с неполным типом вызывает undefined -behavior.

Спектр говорит в §17.4.3.6/2,

В частности, эффекты undefined в следующих случаях:

__ [..]
- если неполный тип (3.9) используется в качестве аргумента шаблона при создании экземпляра компонента шаблона.
__ [..]

Ответ 2

MoveTree является неполным типом внутри его определения. Стандарт не гарантирует создание шаблонов STL с неполными типами.

Ответ 3

Используйте указатель на тип в Vector, это будет переносимым.

struct Move
    {
        int src;
        int dst;
    };

struct MoveTree;

struct MoveTree
    {
        Move move;
        std::vector<MoveTree*> variation;
    };

Ответ 4

Элементы MoveTree в std::vector находятся в выделенном (как в new []) массиве. Только управляющая информация (указатель на массив, размер и т.д.) Сохраняется внутри std::vector внутри MoveTree.

Ответ 5

Нет, он не переносится. 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.

Ответ 6

Вы должны определить конструкторы копирования и операции присваивания для Move и MoveTree при использовании вектора, иначе он будет использовать генерируемые компилятором, что может вызвать проблемы.