0

I have some problem with a returned string: I have a function that returns a string:

std::string foo(const std::string& paramIn)
{
  return ("My message" + paramIn);
}

and I have an exception class:

class MyException : public std::exception
{
private:
  std::string m_msg;

public:
  MyException(std::string& msg) : m_msg(msg) {}
  virtual ~MyException() throw() {}

  virtual const char* what() const throw()
  {
    return m_msg.c_str();
  }
};

The problem appears when I throw an MyException that takes as argument the foo function's return:

throw MyException(foo("blabla"));

It says:

/home/me/my_proj/main.cpp: In member function ‘std::string ConfigFile::getClassifierExtractorType()’:
/home/me/my_proj/main.cpp:79:96: error: no matching function for call to ‘MyException::MyException(std::string)’
     throw MyException(foo("blabla"));
                                    ^
/home/me/my_proj/main.cpp:79:96: note: candidates are:
In file included from /home/me/my_proj/main.hpp:5:0,
                 from /home/me/my_proj/main.cpp:1:
/home/me/my_proj/CMyExceptions.hpp:38:3: note: MyException::MyException(std::string&)
   MyException(std::string& msg) : m_msg(msg) {}
   ^
/home/me/my_proj/CMyExceptions.hpp:38:3: note:   no known conversion for argument 1 from ‘std::string {aka std::basic_string<char>}’ to ‘std::string& {aka std::basic_string<char>&}’
/home/me/my_proj/CMyExceptions.hpp:32:7: note: MyException::MyException(const MyException&)
 class MyException : public MyIOException
       ^

If I just put the returned string in a variable:

std::string msg = foo("blabla");
throw MyException(msg);

It works fine (no errors), why? How to fix this?

1
  • constructor parameter should be const string& Commented Jul 9, 2014 at 12:05

1 Answer 1

5

Rvalues do not bind to non-const lvalue references. Change your constructor:

MyException(std::string const & msg)
//                      ^^^^^

In modern C++, you could even take the string by value:

MyException(std::string msg) noexcept : m_msg(std::move(msg)) { }

This has the added advantage that your exception class can be constructed without itself throwing exceptions, unlike your original code.

Sign up to request clarification or add additional context in comments.

8 Comments

I have also tried to change const std::string foo(const std::string& paramIn), but it did not worked
@thedarksideofthemoon: const rvalues also don't bind to non-const lvalue references.
What other changes will fix it (without noexcept)?
@thedarksideofthemoon: Do exactly what I say in the first code snippet.
Using a value in the ctor was always possible, wasn't it? Only less efficient (no move, no rvalue refs).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.