C++ c++;使用一个线性m.swap(std::stringstream())清除stringstream;?
我一直在使用以下代码清除C++ c++;使用一个线性m.swap(std::stringstream())清除stringstream;?,c++,visual-studio-2013,stringstream,C++,Visual Studio 2013,Stringstream,我一直在使用以下代码清除std::stringstream: m.swap(std::stringstream()); 代码可能取自。最近,我在Visual Studio 2013中编译了代码,收到了以下警告: warning C4239: nonstandard extension used : 'argument' : conversion from 'std::basic_stringstream<char,std::char_traits<char>,std::all
std::stringstream
:
m.swap(std::stringstream());
代码可能取自。最近,我在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
std::swap
函数使用两个非常量参数进行交换。这是因为调用函数时两个参数都会更改。类似地,std::stringstream::swap(…)
函数使用一个非常量参数进行交换
例如:
std::vector<int> vec1, vec2;
std::swap(vec1, vec2);
。。。您试图用m
的内容分配临时std::stringstream()
的内容,这对编译器来说就像一个bug,即使您的目的只是清除m
的内容
要删除警告,只需在执行交换之前声明一个临时的std::stringstream
。像这样:
std::stringstream temp;
m.swap(temp);
这是std::stringstream::swap()的签名。: 如您所见,
swap()
对其参数进行左值引用。正如编译器正确告诉您的那样,右值或临时值无法绑定到左值引用。有些编译器支持非标准扩展,允许您这样做,但我建议您保持在标准的范围内,这样更安全
但是,虽然您可能无法将临时值绑定到左值引用,但可以使用以下std::skipws
技巧将临时值转换为左值:
m.swap(static_cast<std::stringstream&>(stringstream{} >> std::skipws));
在第一个示例中,函数
操作符>>()
返回对流的引用,可以安全地与交换()
一起使用,因为保存参数的引用在函数末尾被销毁。标准不允许使用交换。声明是
template <typename CharT, typename Traits, typename Allocator>
void std::basic_stringstream<CharT, Traits, Allocator>::swap(
basic_stringstream& other);
但是如果您需要支持不支持C++11的编译器,这两种编译器都不起作用,因为在C++03标准中,stringstream
没有swap
函数,也没有公共操作符=
。在这种情况下,您需要:
m.clear();
m.str(std::string());
我无法复制它,老兄,你能发布一些代码吗?@Manu343726 relax dude。在我的VS++2013中,它编译得很好。@Manu343726因为没有其他编译器有非标准的扩展。哦,等等,他们都有。(不可否认,这个特定的扩展确实很糟糕)我在VS2013中做了一个控制台应用程序,我运行了您发布的代码,没有任何优化,我无法复制。它编译得很好,没有警告。或者,先创建临时文件<代码>标准::stringstream().swap(m)
@BillyONeal-确实你也可以这么做!有点类似的问题。。。请参阅关于左值
模板的注释。基本上,您将临时值绑定到非常量左值引用,这是不可能的。您必须使用C++11中的移动语义从_temp(T&&x){return x;}创建对临时模板T&ref_的引用,然后替换m.swap(stringstream())代码>通过m.swap(ref_from_temp(stringstream()))代码>@vsoftco谢谢你的建议。我决定使用Billy的一行程序,因为尽管它与Visual Studio 2010不完全兼容,但它可以与Visual Studio 2010兼容。您如何解释发布的示例编译的事实?使用.str()的问题显然是清除流并不总是对我有效,我不记得为什么。m.clear()
可能还需要执行完全重置。也许还有其他事情。仅使用C++03函数是很困难的。好的,谢谢你提供的额外信息,我很感激。我决定使用std::stringstream().swap(m)代码>因为即使不是C++03,它也可以在VisualStudio2010和2013中工作。我真的希望更好的可移植性,但如果需要的不是clear()和str(std::string()),我不想冒引入bug的风险。谢谢你的回答和想法。@vsoftco它到底是如何工作的?你收到错误了吗?如果是,那是什么?是的,错误:对类型“std::u 1::basic_stringstream”的非常量左值引用无法绑定到不相关类型“std::u 1::basic_istream”的值。
这是代码#include#include使用命名空间std;int main(){stringstream m;m.swap(stringstream{}>>skipws);}
如果您使用move函数添加引用,它会起作用,正如您在前面谈到我的stringstreams问题时提到的那样。
m.swap(static_cast<std::stringstream&>(stringstream{} >> std::skipws));
std::stringstream{}.swap(m):
template <typename CharT, typename Traits, typename Allocator>
void std::basic_stringstream<CharT, Traits, Allocator>::swap(
basic_stringstream& other);
m = std::stringstream();
m.clear();
m.str(std::string());