2015-02-10 142 views
2

我正在使用std :: stringstream来构造一个字符串,然后尝试传递完成的字符串作为一个函数的参考,它需要一个参数std ::字符串&。从std :: stringstream传递std :: string参数作为参数

我在GCC得到一个编译错误:

../src/so.cpp:22:21: error: invalid initialization of non-const reference of type ‘std::string& {aka std::basic_string<char>&}’ from an rvalue of type ‘std::basic_stringstream<char>::__string_type {aka std::basic_string<char>}’ 
../src/so.cpp:12:6: error: in passing argument 1 of ‘void myFunc(std::string&)’ 
make: *** [src/so.o] Error 1 

相同的代码在Windows VS2012编译,但无法在我的Linux和Android版本。这是什么原因?

我可以通过暂时将ss.str()分配给一个临时std :: string,然后通过引用传递该字符串来解决此问题,但这看起来有点愚蠢。干净地做这件事的正确方法是什么?

#include <iostream> 
#include <sstream> 

void myFunc (std::string& msg) 
{ 
    std::cout << msg << std::endl; 
} 

int main (void) 
{ 
    std::stringstream ss; 
    ss << "this is a test"; 

    myFunc (ss.str());    // Fails 

    std::string s = ss.str(); 
    myFunc (s);      // Pass 

    return 0; 
} 
+1

将警告等级设置为'/ W4',VS会告诉你在该线路上正在使用非标准的分机。 – Praetorian 2015-02-10 21:05:15

回答

4

的问题是,myFunc需要一个非-const左值引用。 stringstream::str()按值返回一个字符串。你不能将标准C++中的临时变量绑定到一个非const的左值引用,但是VS有一个允许这样做的“扩展”。这就是编译VS的原因,而不是其他编译器。

const左值引用另一方面可以绑定到右值。因此,从而改变你的函数会使其工作:

void myFunc (const std::string &msg) { /* as before */ } 
+0

非常感谢您的诀窍;说得通。感谢您的其他答案,但是我发现这是最具信息量的。 – Chris 2015-02-10 21:09:50

1

既然你不是里面myFunc写入字符串,接受const引用:

void myFunc (std::string const &msg) 
{ 
    std::cout << msg << std::endl; 
} 

那些可以绑定到临时对象

3

更改此:

void myFunc (std::string& msg) 

这样:

void myFunc (const std::string& msg) 
//   ^^^^^ this will allow temporaries like ss.str() 

有Visual Studio中的版本,将愚蠢允许临时绑定到非const引用。但是,它是危险且无效的C++

-1

所以你有这个错误的原因是ss.str()返回一个常量字符串,而不是一个字符串。 通过创建一个新的字符串,您正在创建一个非常量变量,它被设置为与ss.str()相同的值,因此可以传递到myFunc()中。 制作一个新的字符串,因为你有它可能是最简单的方法来解决这个问题,仍然使用该功能。

+0

但'ss.str()'不返回一个常量字符串。 – juanchopanza 2015-02-10 21:13:04

相关问题