VC2005 Breaking Change: typename’ needed for dependent name to be treated as a type

Original Code:

template<class T>
const T::X& f(T::Z* p);

template<class T, int N>
struct Baz{};

template<class T>
struct Blah : public Baz< T::Type, T::Value>
{
typedef T::X Type;
Type foo();
T::X bar();
operator T::Z();
};

Errors VC2005 issue:

sample.cpp(2) : warning C4346: 'T::X' : dependent name is not a type
prefix with 'typename' to indicate a type
sample.cpp(2) : error C2143: syntax error : missing ';' before '&'
sample.cpp(2) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
sample.cpp(2) : fatal error C1903: unable to recover from previous erro(s); stopping compilation

Code after applying the fix:

template<class T>
const typename T::X& f(typename T::Z* p);

template<class T, int N>
struct Baz{};

template<class T>
struct Blah : public Baz<typename T::Type, T::Value>
{
typedef typename T::X Type;
Type foo();
typename T::X bar();
operator typename T::Z();
};

Thanks,
Ayman shoukry

Comments

  • Anonymous
    June 06, 2007
    It's nice to see the conformance improvements made to VC++. Congratulations!
  • Anonymous
    June 24, 2007
    template <class ItemT> class Container{   public:       class Iterator       {       } ;} ;template <class ItemT> class ContainerAdapter : private Container<ItemT>{   // MSVC compiles this, no problem.  GCC does not.   Container<ItemT>::Iterator mIter ;} ;// How do you get this to compile in Microsoft Visual Studio or GCC?// BTW, GCC does not like "typename".template <class ItemT> class ContainerContainer{   Container<typename ItemT>           mContainer;   Container<typename ItemT>::Iterator mIter ;} ;
  • Anonymous
    June 24, 2007
    The comment has been removed
  • Anonymous
    February 20, 2009
    I'm getting a linker error LNK2019 on vs2005 that I dont understand. Any advice to figured it out are appreicated.Original Code:#include "stdafx.h"template<class T,int BIT>class Test{
    public:typedef struct{    T a;} _BUF;template&lt;typename T&gt;friend Test&lt;T,BIT&gt;operator+(Test&lt;T,BIT&gt;&amp;, Test&lt;T,BIT&gt;&amp;);friend                   &nbsp; Test&lt;T,BIT&gt;BufRestore(_BUF&amp; buf, int exp, int sign );
    };template<typename T,int BIT>Test<T,BIT> operator+(Test<T,BIT>& ss, Test<T,BIT>& tt){  return ss;}template<class T,int BIT>Test<T,BIT> BufRestore( typename Test<T,BIT>::_BUF& buf, int exp, int sign ){
    typename Test&lt;T,BIT&gt;::_BUF&amp; b1;Test&lt;T,BIT&gt; rv;return rv;
    }int _tmain(int argc, _TCHAR* argv[]){
    Test&lt;int,8&gt; t,t1,t2;Test&lt;int,8&gt;::_BUF b1;t = t1+t2;t2 = BufRestore( b1, 10, 0);
      return 0;}Errors VC2005 issue:Compiling...Test.cppCompiling manifest to resources...Linking...Test.obj : error LNK2019: unresolved external symbol "class Test<int,8> __cdecl BufRestore(struct Test<int,8>::_BUF &,int,int)" (?BufRestore@@YA?AV?$Test@H$07@@AAU_BUF@1@HH@Z) referenced in function _wmainC:Documents and SettingsRichardMy DocumentsVisual Studio 2005ProjectsTestDebugTest.exe : fatal error LNK1120: 1 unresolved externalsBuild log was saved at "file://c:Documents and SettingsRichardMy DocumentsVisual Studio 2005ProjectsTestDebugBuildLog.htm"Test - 2 error(s), 0 warning(s)