In the below example, why can't I simply pass a string
to the printFoo()
?
#include <string>
#include <iostream>
using namespace std;
class Foo {
public:
Foo(const Foo &foo) : str(foo.str) {}
Foo(string str) : str(str) {}
string str;
};
void printFoo(Foo foo) {
cout << foo.str << endl;
}
int main() {
Foo foo("qux");
printFoo(foo); // OK
printFoo("qix"); // error: no matching function for call to 'printFoo'
return 0;
}
For whatever reason, I had in my head that a constructor would automatically be determined and used in order to construct an object.
Why can't I do this, but I can pass a char[n]
constant to an argument accepting a std::string
, for example?
There would be two implicit conversions involved:
std::string
Foo
C++ does at most one:
From 4 Standard conversions (N3337)
Also 12.3 Conversions (N3337)
(Emphasis mine)
As others have mentioned, problem is that 2 conversions needed. You may use
s
literal to convert string literal to actualstd::string
DEMO
According to the C++ standard §12.3/4 Conversions [class.conv]:
Thus, the compiler is not allowed to apply two conversions in a row. That is, firstly from
const char[4]
tostd::string
and secondly fromstd::string
toFoo
.For this to work you would need to define an additional constructor:
Thats because the compiler is allowed to consider one conversion.
To do what you need to do the compiler would need to plant two conversions.
If you change this so you pass a string it will work.
The main reason behind all this is string literals have the type
char const[<size>]
NOTstd::string