5

i just wrote a function:

void doSomeStuffWithTheString(const std::string& value) {
...
std::string v = value;
std::cout << value.c_str();
...
}

but then i call this with

doSomeStuffWithTheString("foo");

and it works. So i would have thought that this to work (a const char* to initialise a implicit instance of std::string) the value would have to be passed by value, but in this case is passed by (const) reference.

Is by any chance a implicit temporal std::string instantiated from const char* when the reference is const? if not, then how this possibly work?

EDIT

what happens if the function is overloaded with

void doSomeStuffWithTheString(const char* value);

which one will choose the compiler?

lurscher
  • 25,930
  • 29
  • 122
  • 185
  • You pretty much answered your own question :) – pezcode Jan 25 '12 at 16:49
  • interesting, didn't know that. What does a object need to have so will have such implicit constructors happens on const-by-ref calls (and how to avoid it?) – lurscher Jan 25 '12 at 16:51
  • 1
    The program is ill-formed: `std::string = value;` is not valid and should be rejected by your compiler. – James McNellis Jan 25 '12 at 16:51
  • @lurscher: For how to avoid it, see the `explicit` keyword. You can only prevent implicit conversions on classes you write, however, so I don't know if there's a way to prevent the `const char *` => `std::string` implicit conversion. – Caleb Huitt - cjhuitt Jan 25 '12 at 21:04

4 Answers4

7

The std::string type has an implicit conversion (via constructor) from const char*. This is what allows the string literal "foo" to convert to std::string. This results in a temporary value. In C++ it's legal to have a const & to a temporary value and hence this all holds together.

It's possible to replicate this trick using your own custom types in C++.

class Example {
public:
  Example(const char* pValue) {}
};

void Method(const Example& e) {
  ...
}

Method("foo");
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
0

Yes, a temporary std::string is constructed from the string literal.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
0

Exactly, using std::string default constructor

Andriy Tylychko
  • 15,967
  • 6
  • 64
  • 112
0

"the value would have to be passed by value, but in this case is passed by (const) reference."

There is a C++ feature where it is possible to pass a temporary value (in this case, a temporary std::string implicitly converted from the const char *) to an argument of const-reference (in this case, const std::string &) type.

newacct
  • 119,665
  • 29
  • 163
  • 224