c ++:强制转换运算符与分配运算符与转换构造函数优先级
Posted
技术标签:
【中文标题】c ++:强制转换运算符与分配运算符与转换构造函数优先级【英文标题】:c++: cast operator vs. assign operator vs. conversion constructor priority 【发布时间】:2012-09-02 08:59:56 【问题描述】:让我们有这个代码:
Test1 t1;
Test2 t2;
t1 = t2;
我相信有三种(或更多?)方法可以实现t1 = t2
Test1
中重载赋值运算符
在Test2
中重载类型转换运算符
创建Test1(const Test2&)
转换构造函数
根据我的 GCC 测试,这是使用的优先级:
-
分配运算符
转换构造函数和类型转换运算符(不明确)
const 转换构造函数和 const 类型转换运算符(不明确)
请帮助我理解为什么这个优先级。
我使用此代码进行测试(取消注释某些行以尝试)
struct Test2;
struct Test1
Test1()
Test1(const Test2& t) puts("const constructor wins");
// Test1(Test2& t) puts("constructor wins");
// Test1& operator=(Test2& t) puts("assign wins");
;
struct Test2
Test2()
// operator Test1() const puts("const cast wins"); return Test1();
// operator Test1() puts("cast wins"); return Test1();
;
int main()
Test1 t1;
Test2 t2;
t1 = t2;
return 0;
【问题讨论】:
Test1::Test1(const Test2&)
不是“复制构造函数”,而是“转换构造函数”。
这篇文章解释了为什么转换运算符具有更高的优先级:***.com/questions/1384007/…
【参考方案1】:
语句t1 = t2;
等价于:
t1.operator=(t2);
现在适用重载决议的常规规则。如果有直接匹配,那就是选择的。如果不是,则考虑将隐式转换与(自动生成的,“隐式定义的”)复制赋值运算符一起使用。
有两种可能的隐式、用户定义的转换。所有用户定义的转换计数相等,如果两者都定义,则重载不明确:
通过Test1::Test1(Test2 const &)
转换构造函数将t2
转换为Test1
。
通过Test2::operator Test1() const
转换运算符将t2
转换为Test1
。
【讨论】:
在@Luchian 的第二个ideone 示例中,转换函数获胜,因为它将Test2&
绑定到t2
,而不是const Test2&
。我认为ideone.com/U38vK 也应该是模棱两可的,但似乎 g++ 更喜欢构造函数。
啊哈。如果您要求-pedantic
,g++ 确实称它们为模棱两可。调皮的默认g++。
@KerrekSB:如果转换运算符不是常量,它会击败转换构造函数并且没有歧义。 liveworkspace.org/code/7795254ae49b4d6350f0ede57615e4c6
@JanTuroň:是的,我知道。如果你也将构造函数设为非 const,你可以恢复歧义。
@JanTuroň:完全一样的原因。【参考方案2】:
当我使用以下代码时,优先级优先于构造函数而不是强制转换运算符
#include<iostream>
using namespace std;
class C1;
class C2
int x;
public:
operator C2()
C2 temp;
cout<<"operator function called"<<endl;
return temp;
;
class C1
int x;
public:
C1():x(10)
C1(C2)
cout<<"constructor called"<<endl;
;
int main()
C1 obj1;
C2 obj2;
obj1=obj2;
调用的输出构造函数
【讨论】:
以上是关于c ++:强制转换运算符与分配运算符与转换构造函数优先级的主要内容,如果未能解决你的问题,请参考以下文章
类中移动构造函数的位置/顺序很重要?与移动构造函数结合使用的模板化强制转换运算符
警告:赋值从整数中生成没有强制转换的指针[-Wint-conversion]