字符串流运算符>>作为函数失败,但作为实例工作?

发布于 2024-08-13 13:25:38 字数 1989 浏览 6 评论 0原文

我正在编写简单的代码,将从文件中提取一堆名称、整数对。我正在修改仅使用的现有代码:

string chrom;
unsigned int size;
while ( cin >> chrom >> size ) {
    //  save values
}

但我想使用另一个(类似的)输入文件,该文件具有相同的前两列,但后面跟着其他数据(将被忽略)。 所以我写:

string chrom;
unsigned int size;
string line;
while ( getline(cin, line) ) {
    if( stringstream(line) >> chrom >> size ) {
        // save values
    }
}

但这无法编译,给出典型的淫秽 std lib 模板喷出:

 error: no match for "operator>>" in "std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >(((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >*)(& line))), std::operator|(_S_out, _S_in)) >> chrom"
istream:131: note: candidates are: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>& (*)(std::basic_istream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
[...another dozen lines...]

对。 line 不是 std::string,而是 std::basic_string 的一些变体,等等。 但是,显式实例化 stringstream 是可行的。

string chrom;
unsigned int size;
string line;
while ( getline(genome, line) ) {
    stringstream ss(line);
    if ( ss >> chrom >> size ) {
       // save values
    }
    // Discard remainder of line
}

为什么?第一种情况有什么问题?始终有用的 cplusplus.com 上的示例 basic_io 有效,为什么我的不起作用代码?

更新: 另一个参考点:当提取的第一个值是 int 而不是字符串时,临时字符串流起作用:

unsigned int chrom;  // works as int...
unsigned int size;
string line;
while ( getline(cin, line) ) {
    if( stringstream(line) >> chrom >> size ) {
        // save values
    }
}

I'm writing simple code that will extract a bunch of name, int pairs from a file. I'm modifying existing code that just uses:

string chrom;
unsigned int size;
while ( cin >> chrom >> size ) {
    //  save values
}

But I want to use another (similar) input file that has the same first two columns, but are followed by other data (that will be ignored).
So I write:

string chrom;
unsigned int size;
string line;
while ( getline(cin, line) ) {
    if( stringstream(line) >> chrom >> size ) {
        // save values
    }
}

But this fails to compile, giving the typical obscene std lib template spew:

 error: no match for "operator>>" in "std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >(((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >*)(& line))), std::operator|(_S_out, _S_in)) >> chrom"
istream:131: note: candidates are: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>& (*)(std::basic_istream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
[...another dozen lines...]

Right. line isn't a std::string, but some variation of std::basic_string, etc.
However, explicitly instantiating the stringstream works.

string chrom;
unsigned int size;
string line;
while ( getline(genome, line) ) {
    stringstream ss(line);
    if ( ss >> chrom >> size ) {
       // save values
    }
    // Discard remainder of line
}

Why? What is wrong with the first case? The example basic_io at the always helpful cplusplus.com works, why doesn't my code?

Update:
Another point of reference: the temporary stringstream works when the first value extracted is an int instead of a string:

unsigned int chrom;  // works as int...
unsigned int size;
string line;
while ( getline(cin, line) ) {
    if( stringstream(line) >> chrom >> size ) {
        // save values
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

拥抱我好吗 2024-08-20 13:25:39

C和C++中的一些运算符要求运算符左边的值是左值,即它们可以被修改。

此处 是更完整的解释。

Some operators in C and C++ require that the value on the left of the operator be an lvalue, i.e. that they can be modified.

Here is a more complete explanation.

岁月苍老的讽刺 2024-08-20 13:25:39

因为从 stringstream 中提取的第一个值是 std::string。如果它是一个 int,那么 stringstream(line) 版本就可以工作。

没有成员函数运算符>>在 std::string 的 stringstream 中。因此,临时流不能充当左值。

并不是说我完全理解上述内容......但也许这是一个更好答案的起点。

Because the first value extracted from the stringstream is a std::string. If it was, say, an int, the stringstream(line) version would work.

There's no member function operator>> in stringstream for std::string. Therefore, the temporary stream cannot function as an lvalue.

Not that I fully understand the above... but perhaps it's a starting place for a better answer.

仅此而已 2024-08-20 13:25:38

三组成员函数和一组全局函数重载了这个“提取运算符”(>>),参见http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/

  • 字符串流(行); -- 创建了一个临时对象
  • stringstream ss(line);-- 一个普通对象。

当“chrom”为int时,运算符>>被重载为算术提取器,它是成员函数。普通对象或临时对象都可以正常工作。

当“chrom”为字符串时,运算符>>应该重载为 istream&运算符>> (istream& is, char* str),这是一个全局函数,应该以对象引用作为参数。然而,对于给定的临时对象,我们不允许在标准 C++ 中通过非常量引用来传递临时对象。重载函数无法获取临时对象的引用,除非重载函数定义为 istream&运算符>> (const istream& is, char* str)。不幸的是,事实并非如此。在临时对象的情况下,函数无法重载,因此会发出类似 error: no match for function... 的错误

Three groups of member functions and one group of global functions overload this "extraction operator" (>>), see http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/.

  • stringstream(line); --created a temporary object
  • stringstream ss(line);-- a normal object.

when "chrom" is int, operator >> is overloaded as arithmetic extractor which is member functions. Both the normal object or temporary object work fine.

When "chrom" is string, operator >> should be overloaded as istream& operator>> (istream& is, char* str), this is a global functions which should take the object reference as parameter. However, given temporary object, we are not allowed to pass temporary objects by non-const reference in standard C++. The overload function cannot get the reference of the temporary object unless the overload function is defined as istream& operator>> (const istream& is, char* str). Unfortunately, that is not the fact. The function(s) cannot be overloaded in the temporary object case, and hence giving out the error like error: no match for function...

誰認得朕 2024-08-20 13:25:38

为了扩展 John Weldon 的答案,额外运算符“>>”做两件事:

  1. 提取下一个值并将其放入运算符右侧的变量中。
  2. 增加左侧流的当前位置。

因此,它同时修改其左操作数和右操作数。在您的情况下,左侧操作数是一个临时值,编译器不赞成修改它。

To expand on John Weldon's answer, the extrace operator ">>" does two things:

  1. Extracts the next value and places it into the variable on the right of the operator.
  2. Increments the current position of the stream on the left.

Therefore, it modifies both its left and right operand. In your case, the left-hand operand is a temporary value, and the compiler frowns on modifying it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文