考虑以下代码:
enum ABC : char
{
a, b, c
};
void ff(char c)
{
cout << "char\n";
}
void ff(int i)
{
cout << "int\n";
}
int main()
{
ff(a); // char
}
我可以问为什么要匹配 ff(char)
而不是 ff(int)
?
当我阅读 c ++底漆(第5版)时,我提出了这个问题。在第835页上,作家说:
...我们可以将未枚举的对象或枚举者传递给积分类型的参数。当我们这样做时, enum
值将促进 int
或更大的积分类型...无论其基础类型,对象和枚举者... int
。
我对上述报价的理解是,当传递给期望积分参数的函数时,枚举者将首先将“至少”“至少”施加到 int
中。因此,我希望上述代码可以调用 ff(int)
。实际上,即使是我的Visual Studio编辑器也表明:(对不起,我知道我们应该避免在这里屏幕截图,但我只想显示我所看到的内容)
我也注意到,如果我不明确指定> 的基础类型ABC
,然后将调用 ff(int)
。
因此,我当前的猜测是这样的:如果我们没有明确指定基础类型,则将传递给积分参数传递给积分参数的对象/枚举器将首先将其施加到 int
中。但是,如果明确指定了基础类型,则编译器将首先尝试匹配期望指定类型的过载函数。
我可以问我的猜测是否正确吗?
Consider the following code:
enum ABC : char
{
a, b, c
};
void ff(char c)
{
cout << "char\n";
}
void ff(int i)
{
cout << "int\n";
}
int main()
{
ff(a); // char
}
May I ask why complier matches ff(char)
instead of ff(int)
?
I came up with this question when I was reading C++ Primer (5th Edition). On page 835, the writers state:
... we can pass an object or enumerator of an unscoped enumeration to a parameter of integral type. When we do so, the enum
value promotes to int
or to a larger integral type ... Regardless of its underlying type, objects and the enumerators ... are promoted to int
.
My understanding to the above quote is that, when being passed to a function expecting an integral argument, an enumerator will first be casted "at least" into an int
. So, I'm expecting the above code to call ff(int)
. Actually, even my Visual Studio editor is showing that: (Sorry I know that we should avoid having screenshot here but I just want to show what I saw)

I also noticed that if I don't explicitly specify the underlying type for ABC
, then ff(int)
will be called.
So my current guess goes like this: If we don't explicitly specify the underlying type, then the object/enumerator passed to the integral parameter will first be casted into an int
. But if the underlying type is explicitly specified, then the compiler will first try to match the overloaded function which expects the specified type.
May I ask if my guess is correct?
发布评论
评论(3)
因为具有固定基础类型的枚举可以隐式转换为其基础类型。基础类型为
char
,因此转换为char
是最喜欢的候选人过载。演员是明确的转换。此示例中的转换是隐式的。
确切的首选转换取决于枚举的值。语言规则有点复杂,因此我将从标准中逐字复制:
在这种情况下,
int
是一个正确的猜测不普遍适用。Because an enum with fixed underlying type can implicitly convert to its underlying type. The underlying type is
char
and thus the conversion tochar
is the most preferred candidate overload.A cast is an explicit conversion. The conversion in this example is implicit.
The exact preferred conversion depends on the values of the enum. The language rule is a bit complex, so I'll copy it verbatim from the standard:
In this case,
int
is a correct guess because it is the first type in the list of the quoted standard rule, and it can represent all values of the enum which are 0, 1 2. But the guess does not apply universally.从C ++ 17标准(7.6积分促销)
和(16.3.3.2排名隐式转换序列)
因此,由于由于积分促销的积分促销,因此转换为固定的基础类型CHAR优于基础类型char向INT的转换,因此选择具有参数char的函数作为最可行的函数。
因为根据“ 7.6积分促销”部分的报价#3,枚举类型至少将枚举类型推广到类型
int
。但是,如果您要声明枚举,例如以下演示程序中所示的以下方式:
那么函数调用将是模棱两可的。
From the C++ 17 Standard (7.6 Integral promotions)
and (16.3.3.2 Ranking implicit conversion sequences)
So as the conversion to the fixed underlying type char is better than the conversion of the underlying type char to int due to the integral promotions then the function with the parameter char is selected as the most viable function.
Because according the quote #3 from the section "7.6 Integral promotions" the enumeration type is promoted at least to the type
int
.However if you will declare the enumeration for example the following way as shown in the demonstration program below:
then the function call will be ambiguous.
指定枚举的基础类型将 de exto 将其立即与此基础类型兼容:这就是为什么它是您示例中调用的
char
版本的原因。与C/C ++,
int
一样,隐式的基础类型与往常一样。当您不用枚举指定类型时,就会发生这种情况 - 因此int
版本首先称为。但是在我的编译器上(MSVC2017尝试时),即使是第一种情况也不起作用:我得到了“呼叫'ff'是模棱两可的
> char
版本...可能是因为abc_char
是enum
,而不是“真正的“ char”,而不是真正的“ int”,而是与通过隐式演员。ff
的其他调用不会产生任何错误 -int
版本,没有任何警告。请参阅下面的代码:
ff(a1)
指令甚至不会编译。编译器看到两个候选功能,并且不假定两者中的任何一个。但是此代码适用于所有呼叫/枚举:
您可以在模板中使用
std :: is_same
和一些constexpr
条件,以确保您称呼为“正确的”行为您的功能:Specifying the underlying type for an enum will de facto set it as immediately compatible with this underlying type: that's why it's the
char
version that is called in your example.The implicit underlying type is, as usual in C/C++,
int
. It's what happens when you don't specify a type with your enum - so theint
version is called first.But on my compiler (MSVC2017 when I tried), even the first case don't work: I got a "Call to 'ff' is ambiguous" for the
char
version... Probably becauseABC_char
is anenum
, not "really" a char, and not "really" an int, but is compatible with both through implicit cast.Other calls to
ff
don't produce any error -int
version is called without a single warning.See below code:
The
ff(a1)
instruction won't even compile. Compiler sees two candidate functions and don't assume any of the two.But this code works for all calls/enums:
You could, in template, use
std::is_same
and someconstexpr
conditions to ensure that you call the "correct" behavior for your function: