为什么具有固定的底层类型的枚举的枚举的值可以解析为fct(int)而不是fct(char)? [英] Why does a value of an enum with a fixed underlying type of char resolve to fct(int) instead of fct(char)?
问题描述
This problem came up when answering this question about overload resolution with enums.
虽然 long long
的情况绝对是MSVC2012NovCTP中的错误(根据标准文本和gcc 4.7.1的测试),我不知道为什么会发生以下行为:
While the case for long long
was definitely a bug in MSVC2012NovCTP (according to the standard text and a test with gcc 4.7.1), I cannot figure out why the following behavior occurs:
#include <iostream>
enum charEnum : char { A = 'A' };
void fct(char) { std::cout << "fct(char)" << std::endl; }
void fct(int) { std::cout << "fct(int)" << std::endl; }
void fct(long long) { std::cout << "fct(long long)" << std::endl; }
int main()
{
fct('A');
fct(A);
}
MSVC2012NovCTP和gcc 4.7.1都同意此输出:
Both MSVC2012NovCTP and gcc 4.7.1 agree on this output:
fct(char)
fct(int)
fct(char)
fct(int)
不应将 a
从 charEnum
转换为 char
?为什么
A
被转换为 int
?
Shouldn't A
be converted from charEnum
to char
? Why is A
being converted to int
?
编辑:cl ang compl that;;;;;;;;;;;;;;;那就是说,如果它只被认为是基本类型,我仍然会觉得更直观。
clang complains that the call is ambiguous, which agrees with my interpretation below; that said, I would still find it much more intuitive if it were only considered to be the underlying type.
两个相关标准摘录是§7.2/ 9:
Two relevant standard excerpts are §7.2/9:
枚举器或非范围枚举类型的对象的值通过整数转换为整数促销(4.5)
The value of an enumerator or an object of an unscoped enumeration type is converted to an integer by integral promotion (4.5)
和§4.5/ 4:
底层类型为固定(7.2)的无范围枚举类型的pr值可以转换为其基础类型的prvalue。此外,如果整体推广可以应用于其基础类型,那么其底层类型固定的无范围枚举类型的普通值也可以转换为推广基础类型的普适值。
A prvalue of an unscoped enumeration type whose underlying type is fixed (7.2) can be converted to a prvalue of its underlying type. Moreover, if integral promotion can be applied to its underlying type, a prvalue of an unscoped enumeration type whose underlying type is fixed can also be converted to a prvalue of the promoted underlying type.
所以 charEnum
可以转换为 char
,或 char
的任何整体推广,例如 int
。
So charEnum
can either be converted to char
, or any integral promotion of char
, such as int
.
但是这对我来说是模糊的,因为可以不会说实际上会被选择。如果有什么,这应该是含糊的这个措辞,因为在 char
或其任何促销之间没有偏好。如果您注释掉 fct(int)
,那么调用 是不明确的。为什么 int
特别?
But this is vague to me because "can" doesn't quite say which will actually be chosen. If anything, this should be ambiguous with this wording because no preference is given between char
or any of its promotions. If you comment out fct(int)
, then the call is ambiguous. Why is int
special?
唯一可以想到的是整合促销是递归应用的,但没有
The only thing I can think of is that integral promotions are applied recursively, but nothing I see mandates it.
推荐答案
在C ++ 03中,规则是:
In C++03, the rule was:
未限定枚举类型(7.2 [dcl.enum])的右值可以
转换为以下类型的第一个类型的rvalue,可以
表示枚举的所有值(即
范围bmin到bmax中的值,如7.2 [dcl.enum]中所述):int,unsigned int,
long int,unsigned long int,long long int或unsigned long long int。
An rvalue of an unscoped enumeration type (7.2 [dcl.enum]) can be converted to an rvalue of the first of the following types that can represent all the values of the enumeration (i.e. the values in the range bmin to bmax as described in 7.2 [dcl.enum]): int, unsigned int, long int, unsigned long int, long long int, or unsigned long long int.
在C ++ 03编译器中, int
将被选中,因为它是列表中的第一个
。
In a C++03 compiler, int
would be chosen because it is the first
on the list.
在C ++ 11中,引入了底层类型。因此,通过 685。枚举的积分推广忽略了固定的基础类型,这个措辞已经改为§4.5/ 4引用的段落,从阅读缺陷报告看来,委员会的意图似乎是 fct (char)
(底层类型)被选择。
In C++11, the underlying type was introduced. Accordingly, via 685. Integral promotion of enumeration ignores fixed underlying type , this wording was changed to the paragraph you quoted in §4.5/4 and from reading the defect report, it seems the intention of the committee was for fct(char)
(the underlying type) to be chosen.
然而,根据核心问题1601 ,C ++ 11中的文本实际上使得转换模糊( fct(char)
和 fct(int)
都是可能的,都不是首选)。
However, according to the discussion under core issue 1601, the text in C++11 actually makes the conversion ambiguous (fct(char)
and fct(int)
are both possible and neither is preferred).
以下修正被提出并被接受到C ++ 14:
The following fix was proposed and accepted into C++14:
一种促进基础类型为
固定到其底层类型的枚举的转换比推广到
促进底层类型,如果两者不同。
A conversion that promotes an enumeration whose underlying type is fixed to its underlying type is better than one that promotes to the promoted underlying type, if the two are different.
由于它被报告为C ++ 11中的缺陷编译器应该在C ++ 11模式下应用此修复程序,并调用 fct(char)
。
Since it was reported as a defect in C++11, compilers should apply this fix when in C++11 mode and call fct(char)
.
这篇关于为什么具有固定的底层类型的枚举的枚举的值可以解析为fct(int)而不是fct(char)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!