我有一个简单的结构Wrapper
,通过两个模板化赋值运算符重载来区分:
template<typename T>
struct Wrapper {
Wrapper() {}
template <typename U>
Wrapper &operator=(const Wrapper<U> &rhs) {
cout << "1" << endl;
return *this;
}
template <typename U>
Wrapper &operator=(Wrapper<U> &rhs) {
cout << "2" << endl;
return *this;
}
};
然后我声明 a 和 b:
Wrapper<float> a, b;
a = b;
指派b
to a
将使用上面的非常量模板化赋值运算符重载,并显示数字“2”。
让我困惑的是:如果我声明c
and d
,
Wrapper<float> c;
const Wrapper<float> d;
c = d;
并分配d
to c
,两个赋值运算符重载均未使用,并且不显示任何输出;因此调用默认的复制赋值运算符。为什么分配d
to c
不使用const提供的重载赋值运算符吗?或者相反,为什么分配b
to a
not使用默认的复制赋值运算符?
为什么分配d
to c
不使用const提供的重载赋值运算符吗?
仍然会生成隐式声明的复制赋值运算符,其声明如下:
Wrapper& operator=(const Wrapper&);
运算符模板不会抑制隐式声明的复制赋值运算符的生成。由于参数(const 限定的Wrapper
) 与该运算符的参数完全匹配 (const Wrapper&
),它是在重载决策期间选择的。
未选择运算符模板,并且不存在歧义,因为在所有其他条件相同的情况下,非模板在重载解析期间比模板更匹配。
为什么分配b
to a
不使用默认的复制赋值运算符?
参数(非 const 限定Wrapper
) 是一个更好的匹配操作员模板,需要Wrapper<U>&
比隐式声明的复制赋值运算符(需要一个const Wrapper<U>&
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)