4

为什么我会得到

错误 C2597:对非静态成员的非法引用'derived<<unnamed-symbol>>::T'

当我尝试在 Visual C++ 2010 x64 中编译此代码时?(在 x86 上似乎很好......哪个是正确的?)

struct base { typedef int T; };

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

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

3 回答 3

3

正如 Praetorian 的评论所提到的,问题出在T()默认值上。根据错误详细信息,using base::T显然将编译器混淆为T()对非静态成员函数的调用base而不是类型实例的构造T

这是一个适用于 MSVC 2005 x86 的有趣修复(我没有尝试过任何其他编译器)。请注意,T()保留。这要么消除歧义using base::T,要么只是强制T引用继承的类型而不是那个using(这对编译器来说显然不是一回事)。

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

编辑:尝试更改base为这个,看看你得到什么错误消息:

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

我得到了原来的C2597,还有这个:

错误 C2440:“默认参数”:无法从 '' 转换为 'base::T' 没有构造函数可以采用源类型,或者构造函数重载决议不明确

我不知道那里的编译器是什么意思'',但这可能与base. 如果我删除该using base::T;行,这编译得很好。

于 2012-10-12T22:54:05.800 回答
0

你为什么用using base::T?在基类中定义的类型将在派生类中自动可用。

struct base { typedef int T; };
template< class X >
struct derived : base {};
derived<int>::T v = 0;  // this is OK in C++
于 2012-10-12T22:20:17.010 回答
0

改用这个(应该是不言自明的):

template<class T>
struct derived : base
{
    derived(T = T()) { }
};
于 2012-10-12T22:27:38.413 回答