为什么添加两个字符串文字不使用 operator+?

Why does adding two string literals not use operator+?

编辑:我重新格式化了 post 以便更清楚。

为什么这样做:

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";
}

本质上,第一个例子中的a1a2都是通过隐式转换转换为B对象,并使用operator+(const B&, const B&)相加。

从这个例子开始,我本来希望 "Hello""world" 再次通过隐式构造函数转换为 B 对象,并使用 operator+(const B&, const B&) 添加对彼此。取而代之的是一个错误,它表明 C 风格的字符串不会尝试将用户定义的转换为 B 以便添加。为什么是这样?是否有基本的 属性 可以防止这种情况发生?

1.解释你的编译器错误:

无法使用“+”运算符连接两个字符串文字的原因,
是因为字符串文字只是字符数组,您不能连接两个数组。

数组将隐式转换为其第一个元素的指针。

或如标准所述:

[conv.array]
An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.

你在上面的例子中真正做了什么,
正在尝试将两个 const char 指针相加,但这是不可能的。


2。为什么不隐式转换字符串文字:

由于数组和指针是基本类型,您不能像在 class 示例中那样提供隐式对话运算符。

要记住的主要事情是,std::string 知道如何接受 char[],但 char[] 不知道如何成为 std::string。在您的示例中,您使用了 B 作为 char[] 的替代,但您还赋予了它将自身转换为 A 的能力。


3。备选方案:

您可以通过省略加号运算符来连接字符串文字。

"stack" "overflow"; //this will work as you indented

您可以选择将 "stack" 设为 std::string,然后使用 std::string 的重载“+”运算符:

std::string("stack") + "overflow"; //this will work

在您的第一个示例中,允许重载解析找到您的 operator+:

[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 exactly m parameters are viable.
  • [..]

[C++14: 13.3.2/3]: Second, for F 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 of F. [..]

(您可以自己检查“隐式转换序列”的措辞,看看 operator+ 调用是允许的;规则太冗长,无法保证在此处逐字复制。)

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

[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.