станд :: вектор & л; Т & GT; ошибка компиляции «T не может появиться в константном выражении»

Во-первых, мой код компилируется и отлично работает на Mac OS X с компилятором

i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1

но на Ubuntu с компилятором

g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

это не скомпилируется.

У меня в шапке есть

std::vector<Obstacle::Obstacle*> obstacles;

что дает следующую ошибку компиляции в Ubuntu:

error: ‘Obstacle::Obstacle’ cannot appear in a constant-expression

Любые идеи о том, что мне нужно изменить, чтобы это работало?
Есть ли какой-нибудь волшебный флаг компиляции, который я должен использовать в Ubuntu, чтобы он работал так же, как в OS X?

Спасибо

РЕДАКТИРОВАТЬ: Obstacle это класс.

0

Решение

Вы не можете передать указатель конструктора как сохраненный тип.

Вместо

std::vector<Obstacle::Obstacle*> obstacles;

пытаться

std::vector<Obstacle*> obstacles;
1

Другие решения

По-видимому Obstacle это просто класс.

Удивительно, но также работает следующее, протестированное в g ++ 4.2, g ++ 4.3, g ++ 4.4, clang ++ 2.9 и clang ++ 3.1:

std::vector<Obstacle::Obstacle::Obstacle::Obstacle::Obstacle*> obstacles;

Несколько версий g ++ и несколько версий clang скомпилировали вышесказанное.

g ++ 4.5 и 4.6 имеют проблемы с этой конструкцией. Это похоже на ошибку g ++ версии 4.5 и выше. Так почему это должно быть законно?

Это ошибка в pre 4.5 g ++, clang и, по-видимому, других компиляторах. Соответствующая часть стандарта — 3.4.3.1, пункт 1a:

Если спецификатор вложенного имени назначает класс C, а имя, указанное после спецификатора вложенного имени, при поиске в C является именем введенного класса C (раздел 9), вместо этого считается, что имя Назовите конструктор класса C. Такое имя конструктора должно использоваться только в объявлении-идентификаторе определения конструктора, которое появляется за пределами определения класса.

Другими словами, Obstacle::Obstacle недопустимо, за исключением случаев, когда оно используется во внешнем определении конструктора для класса Obstacle,

Так как же эти компиляторы разбирают это? Эти компиляторы лечат Obstacle::Obstacle как имеющий особое значение только в случае внешнего определения конструктора. Иначе, Obstacle::Obstacle следует введенным правилам имен, но игнорирует тот факт, что это правило здесь не применяется. Obstacle::Obstacle* не является указателем на конструктор, потому что конструкторы не имеют имен. Obstacle::Obstacle* вместо этого означает что угодно Obstacle* означает, когда оценивается в контексте класса Obstacle, Но внутри класса, Obstacle* все еще указатель на экземпляр класса Obstacle, Obstacle::Obstacle* это просто Obstacle*, как есть Obstacle::Obstacle::Obstacle*, и так далее. Куча на столько Obstacleвы хотите, и это все еще просто Obstacle*,

4

По вопросам рекламы [email protected]