为什么添加两个字符串文字不使用operator +(const string&,const string&)?

Sil*_*nic 10 c++ string literals addition

编辑:我重新格式化了帖子以便更清楚.

为什么这样做:

struct A {};

struct B {
    B(A){}
};

void operator+(const B&, const B&) {}

int main()
{
    A a1, a2;
    a1 + a2;
}
Run Code Online (Sandbox Code Playgroud)

这不是吗?

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";
}
Run Code Online (Sandbox Code Playgroud)

本质上,在第一个示例中a1,a2它们都B通过隐式转换转换为对象并使用operator+(const B&, const B&)添加.

从这个例子开始,我希望"Hello"并再次通过隐式构造函数"world"转换为B对象,并使用operator+(const B&, const B&)相互添加.相反,有一个错误,表明C风格的字符串不会尝试进行用户定义的转换B以便添加.为什么是这样?是否存在阻止这种情况的基本属性?

Lig*_*ica 5

在第一个示例中,允许重载解析来查找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]:首先,要成为一个可行的函数,候选函数应具有足够的参数以在数量上与列表中的参数一致.

  • 如果m列表中有参数,则具有精确m参数的所有候选函数都是可行的.
  • [..]

[C++14: 13.3.2/3]:第二,为了F成为一个可行的函数,每个参数都应该存在一个隐式转换序列(13.3.3.1),它将该参数转换为相应的参数F. [..]

(您可以自己检查"隐式转换序列"的措辞,看看该operator+呼叫是否允许;规则过于冗长,无法在此逐字复制.)

但是,在第二个示例中,重载决策受限于基本的算术添加机制(未定义的机制const char[N]或机制const char*),有效地禁止operator+考虑任何函数:

[C++14: 13.3.1.2/1]: 如果表达式中的运算符的操作数没有类或枚举类型,则假定运算符是内置运算符并根据条款5进行解释.

[C++14: 5.7/1]: [..] 另外,两个操作数都应具有算术或非范围的枚举类型,或者一个操作数应是指向完全定义的对象类型的指针,另一个操作数应具有整数或无范围的枚举类型.[..]

[C++14: 5.7/3]: binary +运算符的结果是操作数的总和.

  • 好答案.感谢你和@BaummitAugen特别帮助这个(以及其他所有人). (2认同)