I got xxx is ambiguous
when I'm working on my c++ project. Since the whole project to too huge to upload in here, I made simple example which popup the same error message.
#include <string>
#include <memory>
namespace a {
template <typename T, typename Target>
inline std::shared_ptr<T> getShared(Target const& t)
{
return std::static_pointer_cast<T>(t->shared_from_this());
}
class A : public std::enable_shared_from_this<A>
{
};
}
namespace b {
template <typename T, typename Target>
inline std::shared_ptr<T> getShared(Target const& t)
{
return std::static_pointer_cast<T>(t->shared_from_this());
}
class A : public std::enable_shared_from_this<A>
{
};
void invoke()
{
// ERROR OCCURED!!!
a::A* a;
getShared<a::A>(a);
// But this is compiled without any problem :(
// A* a;
// getShared<A>(a);
}
}
int main(int, char**)
{
b::invoke();
return 0;
}
And here's the error message...
clang++ -c -pipe -g -std=gnu++1y -Wall -W -fPIC -DQT_QML_DEBUG -I../untitled -I. -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-clang -o main.o ../untitled/main.cpp
../untitled/main.cpp:34:2: error: call to 'getShared' is ambiguous
getShared<a::A>(a);
^~~~~~~~~~~~~~~
../untitled/main.cpp:7:27: note: candidate function [with T = a::A, Target = a::A *]
inline std::shared_ptr<T> getShared(Target const& t)
^
../untitled/main.cpp:21:27: note: candidate function [with T = a::A, Target = a::A *]
inline std::shared_ptr<T> getShared(Target const& t)
I tried with both gcc 6.3.0 and clang 3.8.1-24, and both compilers gave me the same error.
Could somebody let me know what is wrong in this code?
You cannot override one virtual function with two or more ambiguous virtual functions. This can happen in a derived class that inherits from two nonvirtual bases that are derived from a virtual base class.
There are two ways to resolve this ambiguity: Typecast char to float. Remove either one of the ambiguity generating functions float or double and add overloaded function with an int type parameter.
When the compiler is unable to decide which function it should invoke first among the overloaded functions, this situation is known as function overloading ambiguity. The compiler does not run the program if it shows ambiguity error.
The comments basically answer the question, but let's wrap it all up.
The compiler's first challenge is to parse getShared<a::A>(a);
. Now this could be operator<
and operator>
, but the compiler first looks up getShared
and notices it's a template, so the <a::A>
is the template argument list.
It's also a function template, so a
is a function argument. At this point, something complex happens. Since a
has type a::A*
, it has an associated namespace . The compiler does a new name lookup of getShared
, now that it knows it's a function with an argument and an associated namespace. This second lookup also finds a::getShared
. That is also a function template, and it can be instantiated with <a::A>
. (SFINAE could exclude it, but the argument is OK).
You now have two instantiations, and overload resolution doesn't resolve their ambiguity.
The name of this second lookup is Argument Dependent Lookup, as mentioned by miradulo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With