Reputation: 210755
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
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
Reputation: 481
Use this instead (should be self explanatory):
template<class T>
struct derived : base
{
derived(T = T()) { }
};
Upvotes: 0
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