2017-09-24 63 views
9

W następnym kodem:niejednoznaczne wywołanie przeciążony matrycy z parametrem (const T const T) lub (char (i) [N], char (i) [m])

#include <iostream> 
using std::cout; using std::endl; 

template <typename T> 
int compare(const T&, const T&) { 
    cout << __PRETTY_FUNCTION__ << endl; 
    return 0; 
} 
template <size_t N, size_t M> 
int compare(const char (&)[N], const char (&)[M]) { 
    cout << __PRETTY_FUNCTION__ << endl; 
    return 0; 
} 

int main(int argc, char *argv[]) { 
    compare("hi", "is"); 
} 

Kiedy I kompiluje kod z g++ -std=c++1y, narzeka:

error: call of overloaded ‘compare(const char [3], const char [3])’ is ambiguous 
    compare("hi", "is"); 

Zgodnie z zasadami szablonu przeciążeniem, żywotne funkcje to:

compare(const T&, const T&) with T = char [3] 
compare(const char (&)[N], const char (&)[M]) with N = 3ul, M = 3ul 

Obaj zapewniają równie dobre (tj. Dokładne) dopasowanie do połączenia. Powinienem więc sprawdzić, który z nich jest bardziej wyspecjalizowany.

Ale według mojej ograniczonej wiedzy, const T& jest bardziej ogólny niż const char (&)[N]. Więc myślę, że compare(const char (&)[N], const char (&)[M]) jest bardziej wyspecjalizowany. Ale dlaczego ten telefon jest niejednoznaczny?

Odpowiedz

10

Pierwsze przeciążenie compare(const T&, const T&) zmusza oba parametry do tego samego typu, podczas gdy drugie przeciążenie nie działa. W związku z tym pierwsze przeciążenie jest bardziej szczegółowe.

Jednak drugie przeciążenie zmusza oba parametry do tablic char, więc jest to bardziej szczegółowe pod tym względem.

Dlatego też nie można powiedzieć, że przeciążenie jest bardziej wyspecjalizowane niż inne, a wynikiem jest błąd niejednoznaczności.

Innym sposobem sprawdzenia tego jest to, że każde przeciążenie może zaakceptować dane wejściowe, których nie ma inne: Tylko pierwsze przeciążenie przyjmuje połączenie, w którym oba argumenty są int&. I tylko drugie przeciążenie zaakceptuje wywołanie, w którym argumenty są char (&)[2] i .

Jeżeli zmienisz drugiego przeciążenie do

template <size_t N> int compare(const char (&)[N], const char (&)[N]) 

będzie naprawić błąd, jak to jest teraz ściśle bardziej specyficzne niż pierwszego przeciążenia.

+0

Zgadzam się na wyjaśnienie, ale rozwiązanie ogranicza użycie drugiego "porównania" do ciągów o równych rozmiarach. – xtofl

+0

Dziękuję. Być może zrozumiałem znaczenie słowa "wyspecjalizowany". Ale jaka jest dokładna zasada "wyspecjalizowanego" w C++? Nie czytałem specyfikacji C++. I czytam książkę C++ Primer. – zhenguoli

+0

@xtofl Był to jeden z przykładów sposobu naprawienia błędu. Innym przykładem może być zmiana pierwszego przeciążenia na dwa różne typy. Nie znając wymagań, nie mogę podać rozwiązania, które je zaspokaja. – interjay