Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么具有固定基础类型char的枚举值解析为fct(int)而不是fct(char)?_C++_C++11_Enums_Overloading_Overload Resolution - Fatal编程技术网

C++ 为什么具有固定基础类型char的枚举值解析为fct(int)而不是fct(char)?

C++ 为什么具有固定基础类型char的枚举值解析为fct(int)而不是fct(char)?,c++,c++11,enums,overloading,overload-resolution,C++,C++11,Enums,Overloading,Overload Resolution,这个问题在回答时出现了 虽然long的情况肯定是MSVC2012NovCTP中的一个bug(根据标准文本和gcc 4.7.1的测试),但我无法理解为什么会出现以下行为: #include <iostream> enum charEnum : char { A = 'A' }; void fct(char) { std::cout << "fct(char)" << std::endl; } void fct(int) { s

这个问题在回答时出现了

虽然
long
的情况肯定是MSVC2012NovCTP中的一个bug(根据标准文本和gcc 4.7.1的测试),但我无法理解为什么会出现以下行为:

#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);
}
#包括
enum charEnum:char{A='A'};

void fct(char){std::cout在C++03中,规则是:

非范围枚举类型(7.2[dcl.enum])的右值可以是 已转换为以下第一种类型的右值,可以 表示枚举的所有值(即 范围bmin到bmax,如7.2[dcl.enum]所述:int,unsigned int, 长整型、无符号长整型、长整型或无符号长整型

在C++03编译器中,会选择int
,因为它是第一个 在名单上


在C++11中,引入了基本类型。因此,通过,该措辞被更改为§4.5/4中引用的段落,从阅读缺陷报告来看,委员会的意图似乎是选择
fct(char)
(基本类型)

但是,根据下面的讨论,C++11中的文本实际上使转换不明确(
fct(char)
fct(int)
都是可能的,两者都不是首选的)

C++14中提出并接受了以下修复:

升级基础类型为的枚举的转换 固定到其基础类型比升级到 升级的基础类型(如果两者不同)


由于它在C++11中被报告为缺陷,编译器应该在C++11模式下应用此修复程序并调用
fct(char)
根据我对当前标准的解释,调用必须是不明确的

根据4.5/4:

基础类型为固定(7.2)的非范围枚举类型的prvalue可以转换为其基础类型的prvalue。此外,如果可以对其基础类型应用整数提升,则基础类型为固定的非范围枚举类型的prvalue也可以转换为提升的基础类型的prvalue

这提供了两种替代升级:一种升级到基础类型,另一种升级到升级的基础类型。因此,在解析重载函数的函数调用时,本段单独引入了模糊性,即应该使用哪种替代方法

然后,第13.3.3段根据“转换序列”
确定过载集的最佳可行功能。具体而言,与此相关的是13.3.3.1(“隐式转换序列”),更具体地说,是13.3.3.1.1(“标准转换序列”),它定义了这些转换序列由哪些基本步骤组成

13.3.3.1.1/1和表12将这些步骤分为四类,其中包括升级和转换,并根据构成这些序列的单个转换类别对转换序列进行排序

在我们的例子中,我们有两个由单个提升步骤组成的单长度转换序列(都是4.5./4允许的)

根据13.3.3.2对转换序列进行排序。特别是,13.3.3.2/3提到,如果:

“S1的等级[即晋升、转换等]比S2的等级好,或者S1和S2的等级相同,并且可以根据下面段落中的规则区分,或者,如果不是那样,[…]”

提及的“以下段落”为13.3.3.2/4,其中规定:

标准转换序列按等级排序:完全匹配的转换比升级的转换好,升级的转换比升级的转换好。除非下列规则之一适用,否则具有相同等级的两个转换序列是不可区分的。

然后,下面是一组在我们的情况下不适用的规则

因此,我们有两个一步转换序列,由具有相同等级的单个提升组成。根据当前标准的上述解释,调用必须是不明确的


但是,就个人而言,我同意需要进行更改,以使到非作用域枚举的固定基础类型的转换比其他可能的转换更可取。

只是猜测:为了保持旧代码正常工作,因为在C++11之前,枚举强制转换为
int
。现在使用类型说明符(
char
在您的情况下,我不知道如何正确调用它),我们只想说应该使用什么类型来表示它,而不是在转换中如何处理它。@leems:嗯,有点像。一种“旧样式”enum强制转换为其基础类型,即
int
unsigned int
long
,等等,直到正确保存所有枚举数值为止。因此,此类型将强制转换为
unsigned int
enum foo{X=0,Y=UINT_MAX};
。尽管您的观点仍然成立:它永远不会“少”但是,由于固定基础类型的整个概念是新的,奇怪的是,由于不兼容的原因,它打破了直观性。对我来说,这听起来像是标准中对整体升级描述的一个缺陷。提到的所有其他类型都被描述为能够升级到零或一个精确指定的升级类型所以当标准的其他部分说“整体提升”时,每个人都知道它到底是什么。但这里听起来好像有两种可能的提升类型??看看这个:-编辑:嗯,我想,它没有显示任何新的东西。我们可以复制一些赞成/反对我的论点的东西吗?哦,等等……也许是“最好的”反对