为什么C++不为枚举类型提供默认"operator>>"函数?



我发现C++为enum类型提供了默认的operator<<函数:

#include <iostream>
using namespace std;
enum OpType {
Select,
Insert
};
int main() {
OpType t = Select;
cout << t;
return 0;
}

运行结果为:

0

虽然不提供默认operator>>功能:

#include <iostream>
using namespace std;
enum OpType {
Select,
Insert
};
int main() {
OpType t = Select;
cin >> t;
return 0;
}

构建它将生成以下编译错误:

prog.cpp: In function ‘int main()’:
prog.cpp:11:6: error: no match for ‘operator>>’ (operand types are ‘std::istream {aka std::basic_istream<char>}’ and ‘OpType’)
cin >> t;
~~~~^~~~
In file included from /usr/include/c++/6/iostream:40:0,
from prog.cpp:1:
/usr/include/c++/6/istream:168:7: note: candidate: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(bool&) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] <near match>
operator>>(bool& __n)
^~~~~~~~
/usr/include/c++/6/istream:168:7: note:   conversion of argument 1 would be ill-formed:
prog.cpp:11:9: error: invalid initialization of non-const reference of type ‘bool&’ from an rvalue of type ‘bool’
cin >> t;
^
In file included from /usr/include/c++/6/iostream:40:0,
from prog.cpp:1:
/usr/include/c++/6/istream:172:7: note: candidate: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(short int&) [with _CharT = char; _Traits = std::char_traits<char>] <near match>
operator>>(short& __n);
^~~~~~~~
/usr/include/c++/6/istream:172:7: note:   conversion of argument 1 would be ill-formed:
prog.cpp:11:9: error: invalid initialization of non-const reference of type ‘short int&’ from an rvalue of type ‘short int’
cin >> t;
^
In file included from /usr/include/c++/6/iostream:40:0,
from prog.cpp:1:
/usr/include/c++/6/istream:175:7: note: candidate: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(short unsigned int&) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] <near match>
operator>>(unsigned short& __n)
^~~~~~~~
/usr/include/c++/6/istream:175:7: note:   conversion of argument 1 would be ill-formed:
prog.cpp:11:9: error: invalid initialization of non-const reference of type ‘short unsigned int&’ from an rvalue of type ‘short unsigned int’
cin >> t;
^
In file included from /usr/include/c++/6/iostream:40:0,
from prog.cpp:1:
/usr/include/c++/6/istream:179:7: note: candidate: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(int&) [with _CharT = char; _Traits = std::char_traits<char>] <near match>
operator>>(int& __n);
^~~~~~~~
/usr/include/c++/6/istream:179:7: note:   conversion of argument 1 would be ill-formed:
prog.cpp:11:9: error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’
cin >> t;
^
In file included from /usr/include/c++/6/iostream:40:0,
from prog.cpp:1:
/usr/include/c++/6/istream:182:7: note: candidate: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(unsigned int&) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] <near match>
operator>>(unsigned int& __n)
^~~~~~~~
/usr/include/c++/6/istream:182:7: note:   conversion of argument 1 would be ill-formed:
prog.cpp:11:9: error: invalid initialization of non-const reference of type ‘unsigned int&’ from an rvalue of type ‘unsigned int’
cin >> t;
^
In file included from /usr/include/c++/6/iostream:40:0,
from prog.cpp:1:
/usr/include/c++/6/istream:186:7: note: candidate: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long int&) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] <near match>
operator>>(long& __n)
^~~~~~~~
/usr/include/c++/6/istream:186:7: note:   conversion of argument 1 would be ill-formed:
prog.cpp:11:9: error: invalid initialization of non-const reference of type ‘long int&’ from an rvalue of type ‘long int’
cin >> t;
^
In file included from /usr/include/c++/6/iostream:40:0,
from prog.cpp:1:
/usr/include/c++/6/istream:190:7: note: candidate: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long unsigned int&) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] <near match>
......

为什么C++不为枚举类型提供默认operator>>函数?

即使忽略没有<<运算符的事实——枚举首先隐式转换为整数——它是如何

标准化的也不明显。读取不存在的枚举值的结果是错误、未指定、实现定义还是未定义?

不同的应用程序需要不同的行为,甚至可能在同一应用程序中。
这让每个人都回到了原点,编写与我们现在相同的代码。

还有一个复杂的问题是,流运算符不是语言本身的一部分,流概念也不是,所以你不能真正让编译器为你生成它们。

没有operator <<采用枚举,您正在调用一个重载取整数,并将枚举值隐式转换为整数。这样做的原因是,采用整数(和其他输入(的operator <<operator >>重载只是普通函数,而不是内置运算符。目前无法为用户定义的类型(例如枚举(提供泛型方法,因为它需要某种编译时反射。

最新更新