std :: istream类型是EqualityComparable吗?

时间:2015-11-16 13:42:26

标签: c++ c++11 equality istream

我的问题会有一个布尔答案:是或否。无论哪一个,有人可以解释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....

2 个答案:

答案 0 :(得分:5)

没有。没有operator==std::istream个对象进行操作。

您能够比较两个std::istream是由std::istream的转换功能引起的不幸后果,特别是operator void*。在表达式i == std::cin中,istd::cin都隐式转换为void*,并比较结果值。这不是很有意义。此转换函数已在C ++ 11中删除(替换为explicit转换函数,在此情况下不会调用此函数),因此如果启用C ++ 11模式,代码将无法编译。

如上所述[{3}},如果您想检查引用i是否引用std::cin,您可以使用&i == &std::cin

答案 1 :(得分:1)

标准C ++流没有==><运算符,因为它们在该上下文中不是很有意义:“流a是&gt;而不是流b”应该是什么意思?

但是,您处理的istream类型无关紧要:只要您没有使用后代类中定义的特定方法(如is_open),基本方法就是共享(例如,提取)。无论您是从string还是istringstream中提取ifstream,只需执行in >> str并让多态采取行动。

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

if ( typeid(in) == typeid(std::cin) )
    // cin
else
   // another istream type

使用重载:

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;
}