c – 绕过自动生成的赋值运算符(VS bug?)
请使用以下代码:
class Foo { Foo const& operator =(Foo const& rhs); // disallow }; struct Bar { public: Foo foo; template <class T> T const& operator =(T const& rhs) { return rhs; } }; struct Baz : public Bar { using Bar::operator =; }; int main() { Baz b1,b2; b1 = b2; } 这无法编译,因为将使用Bar :: operator =的自动生成的赋值运算符,它尝试使用Foo :: operator =,它是私有的.还行吧.所以我在Bar中添加了一个额外的成员: Bar const& operator =(Bar const& b) { return Bar::operator=<Bar>(b); } 现在我们有一个不同的问题.我有两个重载,只能使用其中一个.我正在通过Baz const& ;.我所知道的关于C的一切都表明这应该最终使用非模板版本,因为首先选择匹配的非模板.这也似乎是gcc正在做的事情. Visual Studio似乎不同意: error C2666: 'Bar::operator =' : 2 overloads have similar conversions could be 'const Bar &Bar::operator =(const Bar &)' or 'const T &Bar::operator =<Baz>(const T &)' with [ T=Baz ] while trying to match the argument list '(Baz,Baz)' 我很想在这里相信gcc,因为我对C的理解证实了这一点,并且因为当它不同意Visual Studio时我通常会支持gcc,但我并不像我这样关心它: 在我的非最小例子中,老实说,我根本不需要默认生成的赋值运算符.我对模板运算符完成工作非常满意 – 它会正确完成.但是,因为VS抱怨模板和自动生成的赋值运算符之间的冲突,所以实际上我无法使该模板工作.我已经尝试了以下所有方法: >使赋值运算符保持私有和未实现(不起作用,因为“并非所有重载都是不可行的”) 有没有人对如何解决这个问题有任何好主意?不幸的是我的VS版本不支持自动生成赋值运算符的C 0x“删除”覆盖,因此这不是一个选项,我想不出任何其他方法来解决此错误. 解决方法
在赋值运算符的两个版本之间进行解析时看到的模糊性是由Baz定义中的“using Bar :: operator =”引起的.
无论是在Bar中隐式还是显式定义,非模板版本都采用参数“const Bar&”,它与“Baz”不完全匹配,正如明确解析与模板所需的那样. 有很多方法,但真正的解决方案将取决于真正的来源. 要修复这个例子,我会做这些事情: o防止自动生成const Bar& operator =(const Bar& b)因为它将使用Foo的赋值运算符.您已尝试添加到Bar的定义中的内容将起作用: Bar const& operator =(Bar const& b) { return Bar::operator=<Bar>(b); } o在Baz的定义中使用Bar :: operator =需要去.用包裹Bar :: operator =的函数替换它.如: template <class T> const T& operator =(const T& rhs) { return Bar::operator =(rhs); } (当然,非时髦的代码总会返回* this – 一个Bar&而不是参数的类型.) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |