user541686
user541686

Reputation: 210755

Illegal reference to non-static member... typedef?

Why do I get

Error C2597: Illegal reference to non-static member 'derived<<unnamed-symbol>>::T'

when I try to compile this code in Visual C++ 2010 x64? (It seems fine on x86... which one is correct?)

struct base { typedef int T; };

template<class>
struct derived : base
{
    using base::T;
    derived(T = T()) { }
};

int main()
{
    derived<int>();
    return 0;
}

Upvotes: 4

Views: 1771

Answers (3)

user1201210
user1201210

Reputation: 3809

As Praetorian's comment mentions, the problem is with the T() default value. Based on the error details, using base::T apparently confuses the compiler into searching for T() as a call to non-static member function of base rather than the construction of an instance of type T.

Here's an interesting fix that works in MSVC 2005 x86 (I haven't tried any other compiler). Note that T() is preserved. This either disambiguates using base::T or just forces T to reference the inherited type and not the using one (which are apparently not the same thing to the compiler).

//...
template<class>
struct derived : base
{
    using base::T;
    derived(T = static_cast<T>( T() )) { } //No error
};
//...

Edit: Try changing base to this and see what error messages you get:

struct base { struct T{T(){}}; };

I get the original C2597, but also this:

error C2440: 'default argument' : cannot convert from '' to 'base::T' No constructor could take the source type, or constructor overload resolution was ambiguous

I don't know what the compiler means by '' there, but it's probably a similar problem with the original definition of base. This compiles fine if I remove the using base::T; line.

Upvotes: 3

alexandreC
alexandreC

Reputation: 481

Use this instead (should be self explanatory):

template<class T>
struct derived : base
{
    derived(T = T()) { }
};

Upvotes: 0

BigBoss
BigBoss

Reputation: 6914

Why you use using base::T? Types that defined in base class will be automatically avaiable in derived class.

struct base { typedef int T; };
template< class X >
struct derived : base {};
derived<int>::T v = 0;  // this is OK in C++

Upvotes: 0

Related Questions