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 (4)

  1. ikk says:

    It’s nice to see the conformance improvements made to VC++. Congratulations!

  2. 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 ;

    } ;

  3. mijagourlay says:

    I figured it out.

    Putting "typename" before "Container" in the last line allows it to compile.  

    The "typename" inside the angle brackets is not necessary.

    This works in GCC also.

  4. Richard says:

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

    Compiling 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 _wmain

    C:Documents and SettingsRichardMy DocumentsVisual Studio 2005ProjectsTestDebugTest.exe : fatal error LNK1120: 1 unresolved externals

    Build log was saved at "file://c:Documents and SettingsRichardMy DocumentsVisual Studio 2005ProjectsTestDebugBuildLog.htm"

    Test – 2 error(s), 0 warning(s)

Skip to main content