typename outside of template

This in VS2010sp1 doesn't compile (it does compile with gcc 4.6 though):

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;
}

Error from VS:

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

Which team is right? VS or gcc?

Upvotes: 20

Views: 10835

Answers (3)

In this particular case it would seem that VS2010 is right in rejecting the code:

14.6/5

The keyword typename shall be applied only to qualified names, but those names need not be dependent. The keyword typename shall be used only in contexts in which dependent names can be used. This includes template declarations and definitions but excludes explicit specialization declarations and explicit instantiation declarations.

Upvotes: 3

Prasoon Saurav
Prasoon Saurav

Reputation: 92854

As per C++03, typename and template keywords are not allowed anywhere outside a template, including explicit (full) template specializations. So MSVC++ is correct as per C++03

As per C++0x this code is correct.

Upvotes: 8

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 506905

VS is right on C++03. GCC is right on C++0x.

Now it may be sensible for GCC to also allow this in C++03 mode (there are many things real compilers don't diagnose in C++03 mode that are actually only valid in C++0x), and it may as-well sensible for VS to reject it in C++03 mode.

It doesn't matter anymore whether or not a use of typename QualifiedName happens in a template or not, in C++0x. That is, the following is perfectly legal for C++0x:

#include<vector>

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

In C++03, typename could only be used inside of a template. And the explicit specialization in your code is not a template. There are no template<typename T ...> clauses (all parameters in your code are fixed).

Upvotes: 26

Related Questions