1

I'm coming back to C++ after long years spent on other technologies and i'm stuck on some weird behavior when calling some methods taking std::string as parameters :

An example of call : LocalNodeConfiguration *LocalNodeConfiguration::ReadFromFile(std::string & path) { // ... throw configuration_file_error(string("Configuration file empty"), path); // ... }

When I compile I get this (I cropped file names for readability) :

/usr/bin/g++    -g -I/home/shtong/Dev/OmegaNoc/build -I/usr/share/include/boost-1.41.0   -o CMakeFiles/OmegaNocInternals.dir/configuration/localNodeConfiguration.cxx.o -c /home/shtong/Dev/OmegaNoc/source/configuration/localNodeConfiguration.cxx
    .../localNodeConfiguration.cxx: In static member function ‘static OmegaNoc::LocalNodeConfiguration* OmegaNoc::LocalNodeConfiguration::ReadFromFile(std::string&)’:
    .../localNodeConfiguration.cxx:72: error: no matching function for call to ‘OmegaNoc::configuration_file_error::configuration_file_error(std::string, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)’
    .../configurationManager.hxx:25: note: candidates are: OmegaNoc::configuration_file_error::configuration_file_error(std::string&, std::string&)
    .../configurationManager.hxx:22: note:                 OmegaNoc::configuration_file_error::configuration_file_error(const OmegaNoc::configuration_file_error&)

So as I understand it, the compiler is considering that my path parameter turned into a basic_string at some point, thus not finding the constructor overload I want to use. But I don't really get why this transformation happened.

Some search on the net suggested me to use g++ but I was already using it. So any other advice would be appreciated :)

Thanks

1

3 Answers 3

12

The problem is not basic_string, because basic_string<char, restOfMess> is equivalent to string.

The problem is the function only provides

f(string&, string&) {
//------^

but you are calling as

 f(string("blah"), path);
// ^^^^^^^^^^^^^^

This is a rvalue (temporary object), and a rvalue cannot be bound to a mutable reference. You either need to change the prototype to accept const references or just pass-by-value:

    f(const string&, string&) {
//----^^^^^^
or
    f(string, string&) {

Or provide a mutable reference (if you really need to modify the 1st argument in that function):

string s = "blah blah blah";
f(s, path);
Sign up to request clarification or add additional context in comments.

2 Comments

The funny thing about the internet resources saying to "use g++" is that MSVC detects this and displays a readable warning appropriately. sigh +1
That fixed it (changed the parameter types to const) So yeah I guess I underestimated the importance of the const keyword for the caller. And also underestimated the weirdness of the compiler messages (they were actually truly misleading...) Thank you all !
2

The problem here is that the first (okay, well both, but the first is the one causing the problem) parameter to the configuration_file_error constructor is a non-const reference, and you can't bind a temporary object (like the one you're trying to pass in) to a non-const reference.

The constructor should probably take const references if it doesn't need to modify the strings. Since you're throwing it as an exception, I hope it doesn't really need to modify its parameters because the objects they refer to are probably going to be destroyed when the stack is unwound!

Comments

0

string is just an alias for basic_string<>. From the standard (§21.2) which is undoubtedly copied directly into your header files,

typedef basic_string<char> string;

where basic_string<char> gains two default arguments from

template<class charT, class traits = char_traits<charT>,
class Allocator = allocator<charT> > class basic_string;

These arguments are somewhat arcane and won't ever change unless you manually override them.

(basic_string<wchar_t> is a distinct type which you might encounter with Unicode, however.)

Comments

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.