Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typename outside of template

Tags:

c++

templates

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?

like image 381
There is nothing we can do Avatar asked May 20 '11 18:05

There is nothing we can do


3 Answers

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).

like image 152
Johannes Schaub - litb Avatar answered Jan 03 '23 16:01

Johannes Schaub - litb


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.

like image 40
Prasoon Saurav Avatar answered Jan 03 '23 17:01

Prasoon Saurav


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.

like image 28
David Rodríguez - dribeas Avatar answered Jan 03 '23 18:01

David Rodríguez - dribeas