2016-06-25 18 views
6

Mam przeciążone funkcja w mojej klasie ciąg, jednak nigdy nie zostanie wywołana. Czemu?Funkcja Templated nie nazywa się

template <class T> 
class StringT { 
public: 
    void assign(const T* ptr); 
    template <size_t N> void assign(const T(&ptr)[N]); 
}; 

int main() { 
    StringT<char> str; 
    str.assign("Hello World"); //calls "void assign(const T* ptr)" although type is (const char[12]) 
} 
+1

Interesujące, nie spodziewałem się tego. Zrobiłem nieco bardziej złożony przykład tutaj: http://cpp.sh/7hnfk, który zgadza się z twierdzeniem Microsoft, że auto s = "rzecz"; spowoduje domyślnie const char * (https://msdn.microsoft.com/en-us/library/69ze775t.aspx). – Arunas

Odpowiedz

6

Dalsze odniesienia, pewne konkretne odniesienia do normy to:

13.3.3 Najlepszy opłacalne funkcja

Biorąc pod uwagę te definicje, realną funkcję F1 definiuje się jako lepszą funkcję niż inna żywotna funkcja F2, jeśli dla wszystkich argumentów i, ICSi (F1) nie jest gorszą sekwencją konwersji niż ICSi (F2), a następnie. ..

  • F1 nie jest specjalizacja szablonu funkcja i F2 jest specjalizacja szablonu funkcja ...

W tym przypadku funkcja zakaz matrycy jest (oczywiście) nie jest szablon funkcja specjalizacja i konwersja "Hello World" na char const* nie jest gorszy niż do const char[N], zgodnie z regułami rankingu zdefiniowanymi w Tabeli w sekcji "Standardowe sekwencje konwersji". Zgodnie z tą tabelą zarówno No conversions required, jak i Array-to-pointer conversion są uważane za dokładne dopasowanie w kontekście rozdzielczości przeciążania. Podobnie, jeśli szablony przeciążenia zostaną zmienione na przeciążenie bez szablonu (to jest jako void assign(const T(&ptr)[12]);), kompilacja str.assign("Hello World"); zakończy się niepowodzeniem z powodu niejednoznacznego wywołania.

Aby upewnić się, że funkcja nie szablon nie jest uważane za przeciążenie, istnieje następujący zapis w sekcji „specyfikacja szablon argumentem Explicit”:

Uwaga: lista pusty szablon argument może być używany wskazanie, że dane użycie odnosi się do specjalizacji szablonu funkcji, nawet jeśli widoczna jest funkcja inna niż szablonowa (8.3.5), która w innym przypadku byłaby użyta.

Do tego można użyć str.assign<>("Hello World");.

+0

dziękuję za wyjaśnienie. Czy możesz również opublikować link do tego standardu? – mvidelgauz

+0

Wersje standardowe nie są swobodnie dostępne z tego, co mogę powiedzieć, ale można dostać kopie robocze na http://www.open-std.org/jtc1/sc22/wg21/ pod [ostatni dostępny publicznie szkic] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf) link. Nie jestem pewien, czy jest lepszy sposób, choć ... – mkal

+2

Nadal próbuję pogodzić to z faktem, że: StringT str; char hw_array [] = "Hello World"; str.assign (hw_array); nazywa wersję szablonu – Arunas

3

Gdy istnieje kompilator wyboru wybiera najbardziej wyspecjalizowaną funkcję. Gdy istnieje funkcja non-template niż jest to traktowane jako bardziej wyspecjalizowane niż jakiejkolwiek funkcji szablonu

Szczegóły here

Jeśli chcesz zachować funkcję non-template ale siłą zadzwonić szablon spróbować

str.template assign("Hello World"); 
+0

może zależeć od kompilatora, ale jeśli wersja const T * zostanie skomentowana, zostanie wywołana druga. Nie widzę żadnych interesujących błędów. – Arunas

+0

@Arunas Edytowałem swoją odpowiedź, więc nasze komentarze są teraz nieistotne. Skasowałem mój – mvidelgauz

+0

Czy istnieje sposób, aby kompilator wywoływał funkcję szablonu? – Philinator

Powiązane problemy