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

Typename вне шаблона

Это в VS2010sp1 не компилируется (он компилируется вместе с gcc 4.6):

template<class T>
struct Upcast;

template<>
struct Upcast<signed char>
{
    typedef signed short type;
};

template<>
struct Upcast<char>
{
    typedef typename std::conditional<std::is_signed<char>::value,short, unsigned short>::type type;
};

int main()
{
    Upcast<char>::type a;
    return 0;
}

Ошибка VS:

Error   1   error C2899: typename cannot be used outside a template declaration

Какая команда права? VS или gcc?

4b9b3361

Ответ 1

VS находится прямо на С++ 03. GCC находится прямо на С++ 0x.

Теперь GCC может быть разумным также разрешить это в режиме С++ 03 (есть много вещей, которые реальные компиляторы не диагностируют в режиме С++ 03, которые на самом деле действительны только в С++ 0x), и это может быть разумным для VS, чтобы отклонить его в режиме С++ 03.

Теперь не имеет значения, происходит ли использование typename QualifiedName в шаблоне или нет, в С++ 0x. То есть для С++ 0x совершенно законно:

#include<vector>

int main() {
  typename std::vector<int> v;
}

В С++ 03, typename может использоваться только внутри шаблона. И явная специализация в вашем коде не является шаблоном. Нет предложений template<typename T ...> (все параметры в вашем коде исправлены).

Ответ 2

В соответствии с С++ 03 ключевые слова typename и template не допускаются нигде вне шаблона, включая явные (полные) специализированные шаблоны. Таким образом, MSVС++ корректен в соответствии с С++ 03

В соответствии с С++ 0x этот код верен.

Ответ 3

В этом конкретном случае кажется, что VS2010 прав в отказе от кода:

14.6/5

Ключевое слово typename должно применяться только к квалифицированным именам, но эти имена не должны зависеть. Ключевое слово typename должно использоваться только в контекстах, в которых могут использоваться зависимые имена. Это включает в себя объявления и определения шаблонов, но исключает объявления явных спецификаций и явные декларации о создании экземпляров.