c ++如何保存临时变量的使用

时间:2011-01-14 21:13:11

标签: c++

我在C ++中有以下代码:

string str="a b c";
stringstream sstr(str);
vector<string> my_vec((istream_iterator<string>(sstr)), 
                       istream_iterator<string>());

有没有办法保存sstr的使用,如下所示?

vector<string> my_vec((istream_iterator<string>(str)), 
                       istream_iterator<string>());

3 个答案:

答案 0 :(得分:4)

istream_iterator的参数需要能够绑定到非const引用,而临时则不能。但是,(正如Alf指出的那样),ostream碰巧有一个函数flush(),它返回一个非const引用。所以可能性是:

string str="a b c";
vector<string> my_vec(istream_iterator<string>(
                        static_cast<stringstream&>(stringstream(str).flush())
                        ), istream_iterator<string>());

虽然这是一个眼睛疼痛。如果您担心行太多,请使用函数

vector<string> string_to_vector(const string& str)
{
    stringstream sstr(str);
    return vector<string>(istream_iterator<string>(sstr),
                            istream_iterator<string>());
}

,并提供:

string str="a b c";
vector<string> my_vec = string_to_vector(str);

即使您可以缩短代码,这甚至比您所获得的更清晰,因为现在所做的不是用代码表示,而是用函数的名称表示;后者更容易掌握。


*当然,我们可以添加样板代码来做愚蠢的事情:

class temporary_stringstream
{
public:
    temporary_stringstream(const string& str) :
    mStream(str)
    {}

    operator stringstream&()
    {
        // only persists as long as temporary_stringstream!
        return mStream;
    }

private:
    stringstream mStream;
};

,并提供:

string str="a b c";
vector<string> my_vec((istream_iterator<string>(temporary_stringstream(str))),
                        istream_iterator<string>());

但这和第一个解决方案一样难看。

答案 1 :(得分:0)

您正在使用带有vector的{​​{1}}的双迭代器构造函数将字符串按空格分割为要存储的字符串序列。

istream_iterator需要istream_iterator,而istream没有直接投射。编译器不会推断string,因为stringstream的构造函数采用模板化类型而不是显式istream_iterator。对于编译器而言,这是一个太大的飞跃。

此外,即使编译器实现了这样一种信念的飞跃,它也会生成与您已有的代码相同的代码,所以最终你并没有好转。

更好的方法可能是:

stringstream

需要更少的代码和对象来完成相同的工作。在我的Mac上,这是3203字节代码和273数据,而原始的三行代码是5136字节代码和353数据。 (我在std::vector<std::string> split_words(const std::string& str) { size_t offset = str.find_first_not_of(" \t\r\n"); std::vector<std::string> result; while(offset != std::string::npos) { size_t end = str.find_first_of(" \t\r\n", offset); if(end != offset) result.push_back(std::string(str, offset, end)); offset = str.find_first_not_of(" \t\r\n", end); } return result; } 的末尾添加了return my_vec.size();。)

答案 2 :(得分:0)

Boost有一个专门用于字符串算法的库:查看the Split section:)

std::vector<std::string> vec;
boost::split(vec, "a b c", boost::is_any_of(" ")); 
  // vec == { "a", "b", "c" }

可能是最明智的方法:)