Возможны ли рекурсивные определения типов C ++, в частности, могу ли я поместить вектор <T>в определение T? - PullRequest
29 голосов
/ 29 июня 2011

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

struct Move
{
    int src;
    int dst;
};

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

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

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

Редактировать: я задал второй вопрос в надежде найти хороший способ сделать это.

Ответы [ 6 ]

27 голосов
/ 29 июня 2011

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

Спецификация говорит в §17.4.3.6 / 2,

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

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

4 голосов
/ 29 июня 2011

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

struct Move
    {
        int src;
        int dst;
    };

struct MoveTree;

struct MoveTree
    {
        Move move;
        std::vector<MoveTree*> variation;
    };
4 голосов
/ 29 июня 2011

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

2 голосов
/ 29 июня 2011

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

1 голос
/ 29 июня 2011

Нет, это не портативный. 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.
0 голосов
/ 29 июня 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...