Rozważmy:Pośrednio nazywając kopiowania konstruktora
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;
}
To nie skompilować na deklaracji b3 ('nie można przekonwertować argumentu 1 z 'const char [5]' do 'Foo''). Co ma sens, ponieważ nie ma bezpośredniej metody konwersji const char na Foo. Istnieje jednak sposób na przekonwertowanie const char na std :: string, a następnie użycie go do skonstruowania Foo (co dzieje się w b1 i b2), i to jest to, czego chcę, ponieważ sprawia, że API jest ładniejszy używać (bez konieczności tworzenia instancji Foo lub std :: string jawnie za każdym razem).
Moje pytanie brzmi: czy istnieje sposób, aby kompilator mógł domyślnie wywoływać konstruktor kopii Foo (std :: string)? Innymi słowy, czy istnieje sposób na sporządzenie deklaracji takiej jak praca b3, niech będzie taka sama jak b2, i bez deklarowania konstruktora const char * copy dla Foo? (ta ostatnia rzecz jest oczywista, ale mój prawdziwy kod nie jest oczywiście tak prosty jak ten i wolałbym nie dodawać konstruktorów const char * copy i obsługiwać wszystkich innych inicjalizacji w konstruktorach poprawnie i utrzymywać to w synchronizacja z konstruktorem kopii std :: string).
Niejawna sekwencja konwersji może zawierać tylko jedną konwersję zdefiniowaną przez użytkownika. Pytasz o dwie ('const char *' do 'std :: string', następnie' std :: string' do 'Foo'). Jednym ze sposobów byłoby dodanie przeciążenia konstruktora 'Foo' przy użyciu' const char * '. –
Nitpick: Żaden z konstruktorów, o którym wspomniałeś, nie jest konstruktorem * copy *, jest po prostu konstruktorem. – molbdnilo
Dzięki, "niejawna sekwencja konwersji" to magiczny ciąg, którego szukałem. Rzeczywiście niemożliwe jest zrobienie tego, co chciałem, będę musiał użyć dodatkowego konstruktora. – Roel