Was this page helpful?
Your feedback about this content is important. Let us know what you think.
Additional feedback?
1500 characters remaining
Compiler Warning (level 1) C4346
Collapse the table of content
Expand the table of content

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

Community Additions

© 2015 Microsoft