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

时间:2017-07-21 06:18:26

标签: c++ enums

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

#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>>函数?

2 个答案:

答案 0 :(得分:2)

即使忽略了也没有<<运算符这一事实 - 枚举首先被隐式转换为整数 - 它的标准化程度并不明显。

读取不存在的枚举值的结果是错误,未指定,实现定义还是未定义?

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

还有一个复杂的问题是流操作符不是语言本身的一部分,也不是流概念,因此您无法让编译器为您生成它们。

答案 1 :(得分:-3)

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