Rozważ następujący kod.
void f(double p) {}
void f(double* p) {}
int main()
{ f(1-1); return 0; }
MSVC 2017 tego nie kompiluje. Oznacza to, że istnieje niejednoznaczne przeciążone wywołanie, ponieważ 1-1
jest takie samo, jak 0
i dlatego może zostać przekształcone w double*
. Inne sztuczki, takie jak 0x0
, 0L
lub static_cast<int>(0)
też nie działają. Nawet zadeklarowanie const int Zero = 0
i wywołanie f(Zero)
powoduje ten sam błąd. Działa poprawnie, jeśli Zero
nie jest const
.
Wygląda na to, że ten sam problem dotyczy GCC 5 i niższych, ale nie GCC 6. Jestem ciekawy, czy jest to część standardu C ++, znany błąd MSVC, czy ustawienie w kompilatorze. Pobieżne Google nie przyniosło rezultatów.
źródło
1-1
jest literał całkowity ? Jest to wyrażenie zawierające dwa liczby całkowite z wartością1
i-
operator.-1
). Które, ponieważ domyślny typ jest podpisany , jest oczywiście konieczne i jest oczywiście możliwe (i powszechnie akceptowane).1-1
. C ++ nie ma ujemnych literałów całkowitych.-1
jest wyrażeniem złożonym z1
literału całkowitoliczbowego (typu podpisanego) i-
jednoargumentowego operatora minus. Zobacz także sekcję „Notatki” na cppreference.com .u
, twoje literały są, z definicji, podpisane. Podpisane typy mają wartości ujemne (około 50% możliwych wartości jest ujemnych). To niefortunne, że gramatyka (z tego powodu, którego nie wiedziałbym) wprowadza w błąd w ten sposób i chociaż technicznie (zgodnie z gramatyką) -1 jest literałem dodatnim, negowanym, wszelkimi innymi środkami jest oczywiście negatywny dosłowny. Podobnie jak 3 + 4 jest dosłowne.0U
. Ten sam problem. To, czego nie próbowałem, toenum
wartość. Może nazwany zmieniłby wszystko. Skończyło się na tym, że napisałem długie wyrażenie zdecltype
iremove_reference
.