为什么具有固定的底层类型的枚举的枚举的值可以解析为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)?

查看:217
本文介绍了为什么具有固定的底层类型的枚举的枚举的值可以解析为fct(int)而不是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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆