【问题标题】:Instantiating an ifstream object without using a variable在不使用变量的情况下实例化 ifstream 对象
【发布时间】:2011-11-05 01:42:52
【问题描述】:

如果不将文件存储在变量中,我似乎无法打开文件。我可以这样做:

ifstream blob("somefile");
string line;
blob >> line;

但是当我尝试这个时:

string line;
ifstream("somefile") >> line;

编译器(clang)给出这个错误:

t.cpp:7:23: error: invalid operands to binary expression ('ifstream' (aka 'basic_ifstream<char>') and 'string' (aka 'basic_string<char>'))
    ifstream("thing") >> i;
    ~~~~~~~~~~~~~~~~~ ^  ~
In file included from t.cpp:1:
In file included from /usr/include/c++/4.6/iostream:39:
In file included from /usr/include/c++/4.6/ostream:39:
In file included from /usr/include/c++/4.6/ios:42:
In file included from /usr/include/c++/4.6/bits/ios_base.h:42:
In file included from /usr/include/c++/4.6/bits/locale_classes.h:41:
In file included from /usr/include/c++/4.6/string:53:
/usr/include/c++/4.6/bits/basic_string.h:2679:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>] not
      viable: no known conversion from 'ifstream' (aka 'basic_ifstream<char>') to 'basic_istream<char> &' for 1st argument
    operator>>(basic_istream<char>& __is, basic_string<char>& __str);
    ^
In file included from t.cpp:1:
In file included from /usr/include/c++/4.6/iostream:40:
/    usr/include/c++/4.6/istream:121:7: note: candidate function not viable: no known conversion from 'string' (aka 'basic_string<char>') to
      '__istream_type &(*)(__istream_type &)' for 1st argument
      operator>>(__istream_type& (*__pf)(__istream_type&))
      ^
/usr/include/c++/4.6/istream:125:7: note: candidate function not viable: no known conversion 

... a few more hundred pages of crap ...

1 error generated.

那么,这两者有什么区别呢?对于其他类,直接调用它就可以了。是否涉及一些模板魔法使其模棱两可?

【问题讨论】:

  • @Kerrek:你为什么要删除它?!
  • @KerrekSB 我同意 Tomalak 的观点,看起来像是我的答案。
  • 奇怪的是,(或者也许不是那么奇怪),这在 VC10 中运行良好。也许这就是Kerrek删除他的答案的原因。在这种情况下,VC10 不兼容。
  • @BenjaminLindley:事实上,Visual C++ 是兼容的。 operator&gt;&gt; 重载的规范在 C++11 中发生了变化。
  • 我原来的错误信息实际上是完全不相关的(缺少头文件)。我现在已经粘贴了正确的错误消息。

标签: c++ templates iostream


【解决方案1】:

您发布的代码在 C++03 中无效(即 2011 年 9 月之前的 C++ 语言标准是什么)。在 C++03 中,只有一个 operator&gt;&gt; 重载可以在这里考虑[我已经删除了所有模板代码,因为它不相关]:

istream& operator>>(istream&, string&);

注意std::istream参数是一个非常量引用,所以不能使用临时的std::istream对象。在您的代码中,您尝试在那里使用临时对象。

在 C++11(即当前的 C++ 语言标准)中,还有一个额外的重载,它通过右值引用获取 std::istream 对象。这允许通过该参数传递一个临时值。

Visual C++ 已经支持 C++11 的这一特性,这就是为什么正如 Benjamin Lindley 在评论中指出的那样,如果您使用 Visual C++ 2010 或更高版本,您的代码确实可以编译。如果您使用 -std=c++0x 标志,您的 Clang 版本可能支持此功能。

【讨论】:

  • 有趣的是,21.3 中的 &lt;string&gt; 标头概要与 21.4.8.9 中的重载规范不一致。
  • 我已通知 WG21 规范不一致。同时,对于 C++11,我认为应该有两个重载 operator&gt;&gt; 是合理的,一个采用 istream&amp;,另一个采用 istream&amp;&amp;
猜你喜欢
  • 1970-01-01
  • 2013-06-23
  • 2018-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
相关资源
最近更新 更多