编辑:我已经重新格式化了帖子以使其更加清晰。
为什么这有效:
struct A {};
struct B {
B(A){}
};
void operator+(const B&, const B&) {}
int main()
{
A a1, a2;
a1 + a2;
}
而这不?
struct B {
B(const char*){}
};
void operator+(const B&, const B&) {} //error: invalid operands of types 'const char [6]' and 'const char [6]' to binary 'operator+'|
int main()
{
"Hello" + "world";
}
本质上,在第一个示例中a1
and a2
两者都转换为B
对象通过隐式转换并使用operator+(const B&, const B&)
加上。
从这个例子来看,我本来期望"Hello"
and "world"
转换为B
对象,再次通过隐式构造函数,并使用operator+(const B&, const B&)
来互相补充。相反,会出现错误,表明 C 样式字符串不会尝试将用户定义的转换为B
为了添加。为什么是这样?是否有一个基本属性可以阻止这种情况发生?
在您的第一个示例中,允许重载解析来找到您的operator+
:
[C++14: 13.3.1.2/2]:
如果任一操作数的类型为类或枚举,则可能会声明实现此运算符的用户定义运算符函数或者可能需要用户定义的转换才能将操作数转换为适合内置运算符的类型。在这种情况下,重载决策用于确定要调用哪个运算符函数或内置运算符来实现该运算符。 [..]
[C++14: 13.3.2/1]:
从为给定上下文(13.3.1)构建的候选函数集中,选择一组可行的函数,通过比较参数转换序列以获得最佳拟合来选择最佳函数(13.3.3)。可行函数的选择除了考虑转换序列的排序之外,还考虑自变量和函数参数之间的关系。
[C++14: 13.3.2/2]:
First, 要成为可行的函数,候选函数应具有足够的参数,其数量与列表中的参数一致.
- 如果有
m
列表中的参数,所有候选函数都具有m
参数是可行的。
- [..]
[C++14: 13.3.2/3]
: 第二,对于F
成为一个可行的功能,每个参数都应存在一个隐式转换序列(13.3.3.1) 将该参数转换为相应的参数F
. [..]
(您可以自己检查“隐式转换序列”的措辞,看看operator+
允许打电话;这些规则过于冗长,无法保证在此逐字复制。)
但是,在第二个示例中,重载解析仅限于基本算术加法机制(未为该机制定义的机制)const char[N]
or const char*
),有效禁止任何operator+
考虑的功能:
[C++14: 13.3.1.2/1]:
如果表达式中运算符的操作数不具有类或枚举类型,则假定该运算符是内置运算符并根据第 5 条进行解释。
[C++14: 5.7/1]:
[..] 对于加法,两个操作数都应具有算术类型或无范围枚举类型,或者一个操作数应是指向完全定义的对象类型的指针,另一个操作数应具有整数或无范围枚举类型。[..]
[C++14: 5.7/3]:
二元 + 运算符的结果是操作数之和。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)