C++ 是否保证此枚举与 int 构造函数重载解析?

Does C++ guarantee this enum vs int constructor overload resolution?

考虑这个示例程序:

#include <iostream>

typedef enum { A, B, C } MyEnum;

struct S
{
    S(int) { std::cout << "int" << std::endl; }
    S(MyEnum) { std::cout << "MyEnum" << std::endl; }
};

S f()
{
    return A;
}

int main()
{
    S const s = f();
}

用 clang 和 gcc 编译,这会生成一个可执行文件,在 运行 时打印“MyEnum”。 C++ 标准保证这种行为吗?

当然可以。 return 语句允许隐式构造并且 S(MyEnum) 是完全匹配。

同样适用于 return {A};

但是如果你要S(MyEnum)明确,那么:

  • return A; 将调用 S(int) 作为回退,因为 MyEnum 可以隐式转换为整数。但由于额外的转换,这比 S(MyEnum) 更糟糕的重载候选者,仅根据需要选择。
  • return {A};表示复制列表初始化。它会失败,因为它禁止显式构造函数和隐式转换。
  • return S{A};表示direct-list初始化,会调用S(MyEnum),虽然限制了一些隐式转换,但不影响本例和S(int) 将被调用 S(MyEnum) 被删除。
  • return S(A); 本质上与 return A; 相同,给定指定的 return 类型 S.

是的,S::S(MyEnum)overload resolution because it's an exact match. While S::S(int) requires one more implicit conversion (integral promotion) 中获胜,从枚举到 int

Each type of standard conversion sequence is assigned one of three ranks:

  1. Exact match: no conversion required, lvalue-to-rvalue conversion, qualification > conversion, function pointer conversion, (since C++17) user-defined conversion of class type to the same class
  2. Promotion: integral promotion, floating-point promotion
  3. Conversion: integral conversion, floating-point conversion, floating-integral conversion, pointer conversion, pointer-to-member conversion, boolean conversion, user-defined conversion of a derived class to its base

A standard conversion sequence S1 is better than a standard conversion sequence S2 if

a) S1 is a subsequence of S2, excluding lvalue transformations. The identity conversion sequence is considered a subsequence of any other conversion

b) Or, if not that, the rank of S1 is better than the rank of S2

F1 is determined to be a better function than F2 if implicit conversions for all arguments of F1 are not worse than the implicit conversions for all arguments of F2, and

  1. there is at least one argument of F1 whose implicit conversion is better than the corresponding implicit conversion for that argument of F2

These pair-wise comparisons are applied to all viable functions. If exactly one viable function is better than all others, overload resolution succeeds and this function is called. Otherwise, compilation fails.