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?
Ответы
Ответ 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 должно использоваться только в контекстах, в которых могут использоваться зависимые имена. Это включает в себя объявления и определения шаблонов, но исключает объявления явных спецификаций и явные декларации о создании экземпляров.