使用枚举基础写入枚举时,会出现模糊的超载,但只能使用clang [英] Ambiguous overload when writing an enum with an enum-base, but only with clang

查看:132
本文介绍了使用枚举基础写入枚举时,会出现模糊的超载,但只能使用clang的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用operator<<以写入具有指定基本类型的枚举。令我吃惊的是,似乎我必须自己写出操作员。例如,我想写的代码是

I would like to use operator<< to write an enum with a specified base type. To my surprise, it seems I must write out the operator myself. For example, the code I would like to write is

#include <iostream>
enum myenum : uint16_t
{
    X = 0,
};
int main ()
{
    std::cout << "Value is" << X << std::endl;
    return 0;
}

gcc 4.8和visual studio 2015没有问题。 clang ++ - 3.6错误与

gcc 4.8 and visual studio 2015 have no problems with this. clang++-3.6 errors with

# clang++-3.6 -std=c++11 -O0 ostream.cpp -o test.exe
ostream.cpp:18:29: error: use of overloaded operator '<<' is ambiguous (with operand types
      'basic_ostream<char, std::char_traits<char> >' and 'myenum')
    std::cout << "Value is" << X << std::endl;
    ~~~~~~~~~~~~~~~~~~~~~~~ ^  ~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/ostream:181:7: note: 
      candidate function
      operator<<(unsigned short __n)
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/ostream:189:7: note: 
      candidate function
      operator<<(int __n);
      ^
      ... another 14 candidates along the same lines ...

一般来说,我倾向于相信俚语,当涉及到严格的一致性,所以也许使用真的是模糊的。枚举当然可以转换为其他种类的整数。我希望编译器喜欢相应于枚举的基本类型的版本。

In general, I'm inclined to believe clang when it comes to strict conformance, so maybe the use really is ambiguous. The enum certainly is convertible to other sorts of integers. I hoped that the compiler would prefer the version corresponding to the base type of the enum.

我可以使用一些其他语言功能,而不是枚举...: uint16_t或通过显式地输出运算符,在这种情况下clang也是内容。

I can work around by using some other language feature instead of enum ... : uint16_t or by explicitly typing out the operator in which case clang is also content.

static inline std::ostream & operator<<(std::ostream & out, myenum const & s)
{
    out << static_cast<std::underlying_type<myenum>::type> (s);
    return out;
}

这看起来很荒唐。 clang的行为是预期还是错误?

This looks absurd though. Is clang's behaviour expected or erroneous?

推荐答案

Clang问题。最小化的重现:

Clang problem. Minimized repro:

enum myenum : unsigned short
{
    X = 0,
};

void f(unsigned short);
void f(int);
int main ()
{
    f(X);
    return 0;
}

[conv.prom] / 4:

[conv.prom]/4:


底层类型为
fixed(7.2)的无范围枚举类型的prvalue可以转换为其底层类型的prvalue。
此外,如果可以对其底层类型应用整数提升,则底层类型为
fixed的无范围枚举类型的
a prvalue也可以转换为提升的底层$ pr $的prvalue b类型。

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.

[over.ics.rank] /4.2 - 此项目符号CWG1601 作为针对C ++ 11的DR:

[over.ics.rank]/4.2 - this bullet was added by CWG1601 as a DR against C++11:


标准转换序列按照rank:an Exact
匹配比促销更好的转化,这是比转化更好的
转化。除非以下规则适用,否则具有相同
排名的两个转换序列是无法区分的:

Standard conversion sequences are ordered by their ranks: an Exact Match is a better conversion than a Promotion, which is a better conversion than a Conversion. Two conversion sequences with the same rank are indistinguishable unless one of the following rules applies:


  • [...] li>
  • 如果两者不同,促进其底层类型为
    的枚举与其底层类型固定的转换优于促进
    底层类型的转换。

myenum - > unsigned short myenum - > int 。每[over.ics.rank] /4.2,第一个比第二个更好。这里没有歧义。

myenum->unsigned short and myenum->int have the same rank (Promotion). Per [over.ics.rank]/4.2, the first is better than the second. There's no ambiguity here.

OTOH,GCC默默地调用错误的重载( int 这更好。

OTOH, GCC silently calls the wrong overload (the int one), which isn't that much better.

这篇关于使用枚举基础写入枚举时,会出现模糊的超载,但只能使用clang的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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