use*_*370 7 c++ templates assignment-operator
我有一个简单的结构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;
}
};
Run Code Online (Sandbox Code Playgroud)
然后我宣布a和b:
Wrapper<float> a, b;
a = b;
Run Code Online (Sandbox Code Playgroud)
分配b到a将使用非const模板赋值操作过载从上方和数字"2"被显示.
令我困惑的是:如果我宣布c和d,
Wrapper<float> c;
const Wrapper<float> d;
c = d;
Run Code Online (Sandbox Code Playgroud)
并且分配d给c,既没有使用两个赋值运算符重载,也没有显示输出; 因此调用默认的复制赋值运算符.为什么分配d到c未使用const重载赋值操作符提供?或者相反,为什么分配b给a 不使用默认的拷贝赋值运算符?
Jam*_*lis 18
为什么分配
d到c未使用const重载赋值操作符提供?
仍然会生成隐式声明的复制赋值运算符,该运算符声明如下:
Wrapper& operator=(const Wrapper&);
Run Code Online (Sandbox Code Playgroud)
运算符模板不会抑制隐式声明的复制赋值运算符的生成.由于参数(const-qualified Wrapper)与此运算符(const Wrapper&)的参数完全匹配,因此在重载决策期间选择它.
未选择运算符模板且没有歧义,因为 - 所有其他条件相同 - 非模板在重载决策期间比模板更好地匹配.
为什么分配
b给a不使用默认的拷贝赋值运算符?
参数(非const限定Wrapper)是一个更好的匹配运算符模板,它采用一个Wrapper<U>&比隐式声明的复制赋值运算符(它需要一个const Wrapper<U>&.
从C++ 03标准,§12.8/ 9:
用户声明的拷贝赋值运算符
X::operator=是一个非静态的非模板类的成员函数X与类型的只有一个参数X,X&,const X&,volatile X&或const volatile X&.
§12.8/ 10:
如果类定义未显式声明复制赋值运算符,则会隐式声明一个.
您operator=是模板的事实使它不是复制赋值运算符,因此类的隐式复制赋值运算符仍由编译器生成.
| 归档时间: |
|
| 查看次数: |
5632 次 |
| 最近记录: |