Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
}
like image 575
Chris Avatar asked Dec 20 '22 06:12

Chris


2 Answers

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 */ }
like image 53
juanchopanza Avatar answered Jan 19 '23 00:01

juanchopanza


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.

like image 45
Drew Dormann Avatar answered Jan 19 '23 00:01

Drew Dormann