function overload resolution ambiguity (tsz. function overload resolution ambiguities)
A C++ lehetővé teszi ugyanazon függvénynév több verziójának deklarálását, ha azok paraméterlistájukban különböznek:
void f(int);
void f(double);
void f(std::string);
A híváskor a fordító kiválasztja a legjobban illeszkedő verziót a megadott argumentumok típusa alapján.
A fordító hibát dob, ha több lehetőség ugyanolyan jól illeszkedik, például:
void f(int x);
void f(long x);
f(10); // Melyik legyen? Az int is jó, a long is – NEM EGYÉRTELMŰ!
Ez egy ambiguous overload resolution: a 10
lehet int
, de egy long
is tökéletesen fogadja.
void f(std::string s, int x = 0);
void f(std::string s);
f("hello"); // Ambiguitás: az elsőhöz x=0 alapértelmezett, a második is megegyezik
void f(int);
void f(float);
f('a'); // char -> int is jó, char -> float is jó
template<typename T>
void f(T x);
void f(int x);
f(42); // Mindkettő illeszkedik – de a nem-sablon preferált
Megoldás: töröld a sablont, ha konkrét típust használsz.
void f(const std::string&);
void f(std::string&&);
std::string s = "alma";
f(s); // const std::string&
f("alma"); // melyik? konstrukcióval megy mindkettő felé -> ambiguity lehet
static_cast
Segítsd a fordítót:
f(static_cast<int>(10));
Ha csak egy típust akarsz engedni:
void f(int) = delete;
Használj külön nevet vagy enable_if
-et, ha sablonokról van szó.
Ok | Példa |
---|---|
Túlterhelés hasonló típusokkal | f(int) és f(long)
|
Alapértelmezett paraméter | f(string, int=0) vs f(string)
|
Implicit konverziók | f(int) , f(float) + f('a')
|
Rvalue és lvalue referenciák | f(const T&) vs f(T&&)
|
Sablon és nem sablon versenyez | template<typename T> f(T) vs f(int)
|
std::forward
, std::move
a pontosításra