c ++使用单行m.swap清除字符串流(std :: stringstream());?

时间:2014-05-17 21:12:08

标签: c++ visual-studio-2013 stringstream

我一直在使用以下代码清除std::stringstream

m.swap(std::stringstream());

代码可能取自this SO thread。最近我在Visual Studio 2013中编译了代码,收到了以下警告:

warning C4239: nonstandard extension used : 'argument' : conversion from 'std::basic_stringstream<char,std::char_traits<char>,std::allocator<char>>' to 'std::basic_stringstream<char,std::char_traits<char>,std::allocator<char>> &'
1>          A non-const reference may only be bound to an lvalue

我在使用/ W4的早期版本的Visual Studio中没有收到任何警告。我记得在早期版本中我无法可靠地清除字符串流,这就是我最初使用该代码的原因。

因此可以通过这种方式清除字符串流,如果没有,你可以解释原因吗?还有一种可移植的方式来清除字符串流吗?感谢

编辑:这是请求的代码。使用/W4进行编译以查看警告。

int _tmain(int argc, _TCHAR* argv[])
{
    std::stringstream m;
    m.swap(std::stringstream());

    return 0;
}

3 个答案:

答案 0 :(得分:4)

这里是std::stringstream::swap()的签名:

void swap( basic_stringstream& other );

如您所见,swap()对其参数采用左值引用。正如编译器正确告诉您的那样,右值或临时值无法绑定到左值引用。有些编译器支持允许你这样做的非标准扩展,但我建议你保持在标准的范围内,它会更安全。

但是,虽然您可能无法将临时值绑定到左值引用,但您可以使用此std::skipws技巧转换临时值:

m.swap(static_cast<std::stringstream&>(stringstream{} >> std::skipws));

甚至

std::stringstream{}.swap(m):

在第一个示例中,函数operator>>()返回对流的引用,可以安全地与swap()一起使用,因为保存参数的引用在函数末尾被销毁。 / p>

答案 1 :(得分:1)

std::swap函数需要两个非const 参数进行交换。这是因为调用函数时会更改这两个参数。同样,std::stringstream::swap(...)函数只需要一个非const 参数进行交换。

例如:

std::vector<int> vec1, vec2;
std::swap(vec1, vec2);

在上面的示例中,vec1vec2都被更改了。当你尝试这样做时......

m.swap(std::stringstream());

...您正试图将临时std::stringstream()的内容分配给m的内容,这对编译器来说就像一个bug,即使您的意图只是为了清除m的内容。

要删除警告,只需在执行交换之前声明临时std::stringstream。像这样:

std::stringstream temp;
m.swap(temp);

答案 2 :(得分:1)

标准不允许使用swap。宣言是

template <typename CharT, typename Traits, typename Allocator>
void std::basic_stringstream<CharT, Traits, Allocator>::swap(
    basic_stringstream& other);

这意味着将修改两个stringstream个对象。但是表达式std::stringstream()是一个右值(特别是一个临时的),并且C ++不允许将非常量左值引用绑定到临时值,因为修改临时值通常不是真正的意图。

简单的解决方案是:

m = std::stringstream();

但是如果你需要支持没有C ++ 11支持的编译器,那么两者都不会起作用,因为在C ++ 03标准中,stringstream没有swap函数而没有公共{{1} }。在这种情况下,您需要使用:

operator=