Direct copy constructor call

Consider:

struct Foo { Foo(std::string str) {} }; struct Bar { Bar(Foo f) {} }; int main(int argc, char* argv[]) { Foo f("test"); Bar b1(f); Bar b2(std::string("test")); Bar b3("test"); return 0; } 

This will not compile when declaring b3 ('cannot convert argument 1 from' const char [5] 'to' Foo ''). This makes sense because there is no direct way to convert const char to Foo. However, there is a way to convert const char to std :: string, and then use it to build Foo (this is what happens in b1 and b2), and this is what I want because it makes the API better not to use (it is not necessary to create an instance of Foo or std :: string each time).

So my question is: is there a way to allow the compiler to implicitly call the copy constructor Foo (std :: string)? In other words, is there a way to make an declaration similar to the description of b3, let it be the same as b2, and without declaring the copy char constructor const char * for Foo? (that the latter is the obvious way, but my real code, of course, is not as simple as this, and I would prefer not to add const char * copy constructors and correctly handle all other initialization in the constructors and keep that in sync with the std copy constructor: : string).

+5
source share
2 answers

If C ++ 11 is valid, you can add a delegation constructor to Foo that accepts const char* and just calls another constructor:

 struct Foo { Foo(std::string str) {} Foo(const char* str) : Foo(std::string(str)) {} }; 

Alternatively, you can use C ++ 14 std::string literal:

 using namespace::std::string_literals; Bar b3("test"s); 

You can also emulate a delegation constructor, since both constructors call a separate function:

 struct Foo { Foo(std::string str) { init(str); } Foo(const char* str) { init(str); } void init(std::string str) {} }; 

The disadvantage of the above is that you need to think carefully about everything you did in the initialization lists, which you now need to do in the init body.

+8
source

How to change this:

 struct Bar { Bar(Foo f) {} }; 

to

 struct Bar { Bar(Foo f) {} Bar(std::string f) {} }; 

using polymorphism ...

+1
source

Source: https://habr.com/ru/post/1212202/


All Articles