2012-06-25 13 views
5

Biorąc pod uwagę następujące dwa sygnatury konstruktora, czy powinno być możliwe zbudowanie Couple z Couple("George", "Nora")? Mój kompilator uskarża się z błędem pokazanym poniżej. Jeśli zadzwonię pod numer Couple(std::string("George"), std::string("Nora")), kompiluje się OK. Zgaduję, że istnieje pewien problem z niejawnym castingiem, który zaskakuje mnie, ponieważ chciałem, żeby char * na string był w porządku.Czy poprawne jest posiadanie dwóch niejawnych rzutów podczas konstruowania obiektu w C++?

class Person 
{ 
    public: 
     Person(const std::string& name); 
}; 

class Couple 
{ 
    public: 
     Coordinate(const Person& p1, const Person& p2, const Optional<Person>& = Optional<Person>()); 
}; 

TestCouple.cpp:69: error: no matching function for call to `Couple::Couple(const char[7], const char[5])' 
TestCouple.h:24: note: candidates are: Couple::Couple(const Person&, const Person&, const Optional<fox::Person>&) 
+0

Nie widzę problemu, powinien działać. Powinieneś opublikować pełny minimalny test. – Klaim

+2

Czy "Coordinate" to literówka? Czy nie powinien to być "Para"? – Nawaz

+1

Nie ma czegoś takiego jak "niejawna obsada" w C++. Przesłania to jawne prośby o konwersję przy użyciu specjalnej składni rzutowania. To, czego szukasz, to niejawne konwersje. – PlasmaHH

Odpowiedz

12

Rzeczywiście, sekwencja konwersja nie może zawierać więcej niż jedną grupę użytkowników niejawny zdefiniowana konwersja; standard określa to w C++ 11 12.3/4:

Co najwyżej jedna zdefiniowana przez użytkownika konwersja (konstruktor lub funkcja konwersji) jest niejawnie zastosowana do pojedynczej wartości.

W twoim przypadku, dwa byłyby wymagane (char const[] do std::string do Person), a więc niejawna konwersja nie jest możliwa.

6

Masz rację, że wystąpił problem z niejawną konwersją. Wykona tylko jedną niejawną konwersję dla wartości, więc możesz na przykład wykonać: Couple(std::string("a"), std::string("b")) lub Couple(Person("a"), Person("b")), ale Couple("a", "b") wymagałoby kompilatora, aby umieścić dwie niejawne konwersje na wartość. Nie jest to dozwolone przez standard, ponieważ spowodowałoby to kod, który może być trudny do zrozumienia i skompilowany kosztowo.

1

Łańcuchowa niejawna konwersja jest niedozwolona. Jeśli A można niejawnie przekonwertować do B i B można niejawnie przekonwertować do C, to nie znaczy, że A można niejawnie przekonwertować do C.

//given three objects as 
A a; 
B b' 
C c; 

//premises 
b = a; //a can convert into b (implicitly) 
c = b; //b can convert into c (implicitly) 

//then it does not follow this 
c = a; //a CANNOT convert into c (implicitly) 

//you need to write this at least 
c = static_cast<B>(a); //ok 
+0

"Nie oznacza to, że A może domyślnie przekształcić w C._", co jest poprawne. Nitpick: stwierdzenie, że "b = a" jest ważne "nie jest równoznaczne z stwierdzeniem" A może konwertować na B ". – curiousguy

+0

@cualnyguy: Wyjaśnij, co mówisz. Dlaczego "b = a" jest ważne na pierwszym miejscu? – Nawaz

+0

Zakładając, że B jest typem klasy, 'b = a' jest prawidłową poprawnością przeciążenia _iff_ może znaleźć najlepsze dopasowanie dla' b.operator = (a) '. Równie dobrze można napisać 'foo (a, b)', dla odpowiednich przeciążeń 'foo'. – curiousguy

Powiązane problemy