- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想使用 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 short
和 myenum
->int
具有相同的排名(提升)。根据 [over.ics.rank]/4.2,第一个比第二个好。这里没有歧义。
OTOH,GCC 默默地调用了错误的重载(int
重载),这并没有好多少。
关于c++ - 使用枚举基编写枚举时出现不明确的重载,但仅使用 clang,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34336024/
我是一名优秀的程序员,十分优秀!