为什么这样做:
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和a2都通过隐式转换转换为B对象,并使用运算符(const B& const B&)来添加.
从这个例子中,我将期望“Hello”和“world”通过隐式构造函数再次转换为B对象,并使用operator(const B& const B&)来相互添加.相反,有一个错误,这表示C样式的字符串不会尝试用户定义的转换为B以添加.为什么是这样?是否有根本的财产阻止这一点?
解决方法
[C++14: 13.3.1.2/2]:
If either operand has a type that is a class or an enumeration,a user-defined operator function might be declared that implements this operator or a user-defined conversion can be necessary to convert the operand to a type that is appropriate for a built-in operator. In this case,overload resolution is used to determine which operator function or built-in operator is to be invoked to implement the operator. [..]
[C++14: 13.3.2/1]:
From the set of candidate functions constructed for a given context (13.3.1),a set of viable functions is chosen,from which the best function will be selected by comparing argument conversion sequences for the best fit (13.3.3). The selection of viable functions considers relationships between arguments and function parameters other than the ranking of conversion sequences.
[C++14: 13.3.2/2]:
First,to be a viable function,a candidate function shall have enough parameters to agree in number with the arguments in the list.
- If there are
m
arguments in the list,all candidate functions having exactlym
parameters are viable.- [..]
[C++14: 13.3.2/3]
: Second,forF
to be a viable function,there shall exist for each argument an implicit conversion sequence (13.3.3.1) that converts that argument to the corresponding parameter ofF
. [..]
(您可以自己检查“隐式转换序列”的措辞,看看运算符电话是允许的;这些规则太冗长,无法保证在这里逐字复制.)
然而,在第二个例子中,重载分辨率被限制为一个基本的算术加法机制(一个没有为const char [N]或const char *定义),有效地禁止任何运算符函数被考虑:
[C++14: 13.3.1.2/1]:
If no operand of an operator in an expression has a type that is a class or an enumeration,the operator is assumed to be a built-in operator and interpreted according to Clause 5.
[C++14: 5.7/1]:
[..] For addition,either both operands shall have arithmetic or unscoped enumeration type,or one operand shall be a pointer to a completely-defined object type and the other shall have integral or unscoped enumeration type. [..]
[C++14: 5.7/3]:
The result of the binary + operator is the sum of the operands.