std :: istream类型是EqualityComparable吗?

GSi*_*GSi 4 c++ equality istream c++11

我的问题会有一个布尔答案:是或否.无论它是什么,有人可以解释GNU-g ++ 4.9.2和clang 3.5如何编译以下代码,而GNU-g ++ 5.1.1不再接受它,声称没有匹配operator==

对于最后一个编译器,如何改变它,以便获得相同的结果,即operator>>能够以这种简单的方式区分它是由标准输入流还是由其他东西调用?

  # include <iostream>
  # include <fstream>

  struct S {};

  std::istream& operator >> (std::istream& i, S& s)
   {
    if(i == std::cin) std::clog << "this is standard input\n";
    else std::clog << "this is some other input stream\n";

    return i;
    }

  int main(int narg, const char ** args)
   {
    S s;
    std :: cin >> s;
    std::ifstream inp(args[1]);
    inp >> s;
    }
  // to be executed with the name of an existing
  // disk file on the command line....
Run Code Online (Sandbox Code Playgroud)

cpp*_*ner 5

没有.没有operator==std::istream物体进行操作.

你能够比较两个std::istreams是std::istream具体的转换功能造成的不幸后果operator void*.在该表达式中i == std::cin,既istd::cin被隐式转换为void*,将得到的值进行比较.这不是很有意义.此转换函数已在C++ 11中删除(由explicit转换函数替换,在这种情况下不会调用),因此如果启用C++ 11模式,代码将无法编译.

正如指出这里,如果你想检查是否参考i指的是std::cin,你可以使用&i == &std::cin.


edm*_*dmz 2

标准 C++ 流没有==, >,<运算符,因为它们在该上下文中没有多大意义:“流 a > 比流 b”应该意味着什么?

但是,您处理的类型并不重要istream:只要您不使用后代类中定义的特定方法(例如is_open),基本方法就是共享的(例如提取)。无论您是string从 aistringstream还是 a中提取 a ifstream,您都只需这样做in >> str并让多态性发挥作用即可。

如果您确实想知道 的多态类型istream,您可以使用typeid或者简单地使用函数重载。在你的情况下,使用 RTTI( typeid)

if ( typeid(in) == typeid(std::cin) )
    // cin
else
   // another istream type
Run Code Online (Sandbox Code Playgroud)

使用重载:

std::istream& operator >> (std::istream& i, S& s)
{
     std::clog << "this is standard input\n";   
     return i;
}

std::ifstream& operator>>(std::ifstream& i, S& s)
{
     std::clog << "this is some file input stream\n";
     return i;
}
Run Code Online (Sandbox Code Playgroud)