将来自 std::string 流的 std::string 引用作为参数传递

Passing std::string reference from std::stringstream as parameter

我正在使用 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;
}

由于您没有写入 myFunc 中的字符串,请接受常量引用:

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

那些可以绑定到临时对象

问题是 myFunc 采用非常量左值引用。 stringstream::str() returns 一个按值排列的字符串。您不能在标准 C++ 中将临时值绑定到非常量左值引用,但 VS 有一个 "extension" 允许这样做。这就是它在 VS 而不是在其他编译器上编译的原因。

const 另一方面,左值引用可以绑定到右值。因此,修改您的函数将使其工作:

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

改变这个:

void myFunc (std::string& msg)

对此:

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

Visual Studio 的某些版本 愚蠢地 允许临时绑定到非常量引用。但是,它 危险且无效的 C++

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