Reputation: 541
Suppose I have a class
class Foo
{
public:
Foo(int x);
Foo(std::string s);
}
I want to be able to initialize objects like this
int main()
{
Foo f1 = "some string"
}
rather than
int main()
{
Foo f1("some string");
}
So far I am getting a compiler error: error: invalid conversion from 'const char*' to 'int' [-fpermissive]|
All I can think of is making an additional constructor that takes char* argument, but I was hoping to avoid this redundancy.
Upvotes: 2
Views: 130
Reputation: 208456
While it might not seem obvious, there are two user defined conversions in the case of copy-initialization:
Foo f1 = "some string";
In the expression above, Foo f1 =
is a call to Foo(Foo const &)
with the right hand side as argument. For that, the compiler would need to figure out how to go from literal (array of N char) to Foo
, and that requires a user defined conversion to std::string
(contructor taking const char*
) and a second user defined conversion from std::string
to Foo
(second constructor above).
Now, it might not seem obvious why the second case does not require the same number of conversions… when you do Foo f("something");
the compiler considers the three overloads:
Foo(int);
Foo(std::string);
Foo(Foo const &);
There is no conversion from literal to int
, so the first is discarded. There is a one-step conversion from literal to std::string
(by means of the constructor taking const char*
) so this is a viable candidate. As seen above, there is no one-step conversion from literal to Foo
, so that one is also discarded and the only viable candidate is picked up.
The language is quite clear in that there can only be on user defined conversion in a conversion sequence, so there is nothing that can be done there. So you are left with either providing another constructor or making sure that the right hand side is a std::string
. For that you could either explicitly convert (valid in C++03):
Foo f1 = std::string("something");
You might also just leave this to the user and require that they do direct initialization instead of copy initialization. Or you can add a constructor that takes the const char*
.
Upvotes: 2