简体   繁体   中英

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

I am using std::stringstream to construct a string and then attempting to pass the completed string as a reference to a function which takes as a parameter a std::string&.

I am getting a compilation error on 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

The same code is compiling on Windows VS2012, but fails on my Linux and Android builds. What is the reason for this?

I can work around the issue by temporarily assigning ss.str() to a temporary std::string and then passing that string by reference, but this seems slightly silly. What is the correct way to do this cleanly?

#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;
}

The issue is that myFunc takes a non-const lvalue reference. stringstream::str() returns a string by value. You cannot bind a temporary to a non-const lvalue reference in standard C++, but VS has an "extension" that allows this. That is the reason it compiles on VS and not on other compilers.

const lvalue references, on the other hand, can bind to rvalues. So modifying your function thus would make it work:

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

Change this:

void myFunc (std::string& msg)

to this:

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

There are versions of Visual Studio that will foolishly allow a temporary to bind to a non-const reference. It is dangerous and not valid C++ , however.

Since you're not writing to the string inside myFunc , accept a const reference:

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

Those can be bound to temporary objects

So the reason that you are having this error, is that ss.str() returns a const string, not a string. By creating a new string you are creating a non-const variable that is set to the same value as ss.str() and thus can be passed into myFunc(). Making a new string as you have it is probably the easiest way to fix this and still use the function as is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM