Consider the following:
class Foo {
public:
Foo (const char *in) {
printf ("C string constructor called\n");
}
Foo (std::string const &in) : Foo(in.c_str()) {
printf ("C++ string constructor called\n");
}
};
Foo bar ("I never asked for this");
//C string constructor called
So, a constant string
is treated as a const char *
one.
But what would change, if we make a std::string
constructor "primary"?
Can we expect that an std::string
object would be created and passed to corresponding constructor without calling a C-string related one?
class Foo {
public:
Foo (std::string const &in) {
printf ("C++ string constructor called\n");
}
Foo (const char *in) : Foo(std::string (in)) {
printf ("C string constructor called\n");
}
};
Foo bar ("I never asked for this");
//C++ string constructor called
//C string constructor called
Again, the C-string constructor was called first.
Is this behavior described in C++ standard, or is it compiler-related?
Would this work the same way for e.g. templates or overloaded functions?
I compiled with GCC 7.3.0 (MSYS2 x64).
"I never asked for this"
is a string literal which consists of const char
elements:
Foo bar ("I never asked for this"); // calls Foo (const char *in)
Thus, Foo (const char *in)
will always get selected by overload resolution regardless of the "order" in which you declare your constructors.
As seen in your 2nd example,
Foo (const char *in) : Foo(std::string (in))
The delegating constructor is selected and will call the target constructor, as selected by the only member of the initialization list.