首页 文章

将临时istringstream对象传递给istream_iterator <string>

提问于
浏览
3

我有一个关于以下代码的问题,该代码标记了一个字符串(用空格分隔标记) .

#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

int main()
{
    string s="And I feel fine ...";
    istringstream ss(s);
    vector<string> tokens{istream_iterator<string>(ss),{}};
    for(auto& elem: tokens)
        cout << elem << endl;
}

这完全没问题 . 另一方面,如果我尝试将临时 istringstream 对象传递给 istream_iteratormain 内的第3行),例如

vector<string> tokens{istream_iterator<string>(istringstream(s)),{}};

我收到编译时错误 error: no matching conversion for functional-style cast from 'istringstream' (aka 'basic_istringstream<char>') to 'istream_iterator<string>'

我相信这是因为我不能将临时rvalue绑定到非const左值引用, istream_iterator 的构造函数将引用作为参数 . 有没有办法从临时构建 istream_iterator<string> ?我不能在临时对象上使用 std::ref ...

谢谢!

1 回答

  • 3

    使用 std::skipw 技巧:

    std::vector<std::string> tokens{
        std::istream_iterator<std::string>(std::istringstream(s) >> std::skipws), {}
    };
    

    这是因为提取器返回对流的左值引用,并且设置 std::skipw 将没有任何效果,因为它在所有流上默认启用 . 要在一般情况下使用它,您可能希望拥有一个采用通用引用的函数,然后返回对该对象的引用:

    template<typename T>
    T& lvalue(T&& x)
    {
        return x;
    }
    
    // ...
    std::istream_iterator<std::string>(lvalue(std::istringstream(s)));
    

    确保在完整表达式之后没有使用引用,否则您将有一个悬空引用,因为临时将已被破坏 .

相关问题