gpt4 book ai didi

c++ - 使用枚举基编写枚举时出现不明确的重载,但仅使用 clang

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:35:22 24 4
gpt4 key购买 nike

我想使用 operator<< 来编写一个具有指定基类型的枚举。令我惊讶的是,似乎我必须自己写出运算符。比如我想写的代码是

#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 错误

# 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 ...

总的来说,在严格遵守方面,我倾向于相信 clang,所以也许使用确实是模棱两可的。枚举当然可以转换为其他类型的整数。我希望编译器更喜欢与枚举的基类型对应的版本。

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

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

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

最佳答案

clang 问题。最小化重现:

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

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

[conv.prom]/4:

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:

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:

  • [...]
  • 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.

myenum->unsigned shortmyenum->int 具有相同的排名(提升)。根据 [over.ics.rank]/4.2,第一个比第二个好。这里没有歧义。

OTOH,GCC 默默地调用了错误的重载(int 重载),这并没有好多少。

关于c++ - 使用枚举基编写枚举时出现不明确的重载,但仅使用 clang,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34336024/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com