Compiler Warning (level 1) C4346
Collapse the table of content
Expand the table of content
The document is archived and information here might be outdated

Compiler Warning (level 1) C4346

Error Message

'name' : dependent name is not a type

The typename keyword is required if a dependent name is to be treated as a type. This is a breaking change in the Visual C++ .NET 2003 compiler, made in order to conform to the ISO C++ standard.

See Summary of Compile-Time Breaking Changes for more information.

For code that works the same in all versions of Visual C++, add typename to the declaration.

The following sample generates C4346:

// C4346.cpp
// compile with: /WX /LD
template<class T>
struct C {
   T::X* x;   // C4346
   // try the following line instead
   // typename T::X* x;

The following samples shows other examples where the typename keyword is required:

// C4346b.cpp
// compile with: /LD /W1
template<class T>
const typename T::X& f(typename T::Z* p);   // Required in both places

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

template<class T>
struct M : public L<typename T::Type, T::Value> 
{   // required on type argument, not on non-type argument
   typedef typename T::X   Type;
   Type f();   // OK: "Type" is a type-specifer
   typename T::X g();   // typename required
   operator typename T::Z();   // typename required    

and this,

// C4346c.cpp
// compile with: /LD /WX
struct Y {
   typedef int Y_t;

template<class T>
struct A {
   typedef Y A_t;

template<class T>
struct B {
   typedef /*typename*/ A<T>::A_t B_t;   // C4346 typename needed here
   typedef /*typename*/ B_t::Y_t  B_t2;   // typename also needed here
© 2016 Microsoft