C++ strange ambiguous call to overloaded function
'void a(foo)' [found using argument-dependent lookup]
Well, surprisingly MSVC has a very good error explanation:
Following the standard, inside a function the compiler look for symbols in the current namespace and in the namespace where the type of the arguments are defined.
In the first case a
is in foobar
and in the namespace of the argument type foo
: the global namespace, making it ambiguous.
In the second case a
is in foobar
but not in the namespace of the argument type bar::foo
: with is bar
.
Strange ambiguous call to overloaded function error
Look at the error message from gcc:
a.cpp:16: error: call of overloaded ‘function(double, double)’ is ambiguous
a.cpp:3: note: candidates are: void function(int, int)
a.cpp:9: note: void function(float, float)
A call to either function would require truncation, which is why neither is preferred over the other. I suspect you really want void function(double y,double w)
. Remember that in C/C++, the default floating-point type for literals and parameter passing is double, NOT float.
UPDATE
If you really don't want to change the function signature from float to double, you can always use literals that are typed as float. If you add the suffix f to the floating point numbers, they will be typed float.
Your examples would then be function(1.2f, 2f)
and function(1, 2.2f)
.
fpclassify': ambiguous call to overloaded function
The error message like fpclassify': ambiguous call to overloaded function
is always accompanied by notes. For example, for a simple program
#include <cmath>
int main() {
std::isnan(5);
}
VS complains:
corecrt_math.h(415): error C2668: 'fpclassify': ambiguous call to overloaded function
corecrt_math.h(300): note: could be 'int fpclassify(long double) throw()'
corecrt_math.h(295): note: or 'int fpclassify(double) throw()'
corecrt_math.h(290): note: or 'int fpclassify(float) throw()'
corecrt_math.h(415): note: while trying to match the argument list '(_Ty)'
with [ _Ty=int ]
<source>(3): note: see reference to function template instantiation 'bool isnan<int>(_Ty) throw()' being compiled
with [ _Ty=int ]
From these notes we can infer that _Ty
is int
and that std::nan
was called on the line 3 of our source code. Take a look at the full compiler output for your compilation, it will tell you the exact place in your code where the error is triggered.
Error: ambiguous call to overloaded function
You can press F12 on that function.
Update
Based on comments from the OP, the problem was due to a definition of acos
being brought in from G3D::
. Using std::acos as opposed to acos
will remove the ambiguity.
Why does this program in c++, visual studio code shows error
Type area(5.5f)
to force the value to be a float.
The compiler does not know if it should cast your double value to an int or a float. Therefore, it is ambiguous.
MSVC - C2668 ambiguous call to overloaded function - Is it a compiler bug?
For the call Foo<int>()
the compiler can deduce Foo<int>()
for the first template, and Foo<int>(void)
for the second.
From temp.deduct.partial#11:
... if G has a trailing function parameter pack for which F does not have a corresponding parameter, and if F does not have a trailing function parameter pack, then F is more specialized than G.
This is a tie breaker, and the first template is selected.
Not being able to resolve the ambiguity appears to be a MSVC bug.
c++ templates and ambiguous call to overloaded function
This looks like a bug in MSVC and GCC. The call should resolve to the second overload (Clang and EDG are doing that).
For the call B::func(g, dt, bx)
, name lookup finds the two func
templates. Template argument deduction and substitution is performed on each of them in order to generate function template specialization declarations that can subsequently participate in overload resolution. Deduction succeeds for both templates and we're left with two specializations:
void B::func<BX, int, G<BX<int>, int>>(const G<BX<int>, int>&, const DT<BX, int>*, BX<int>&);
void B::func<BX, int, int> (const G<BX<int>, int>&, const DT<BX, int>*, BX<int>&);
The two functions have identical parameter declaration clauses, so clearly overload resolution cannot distinguish between them based on conversions from the arguments of the call; it has to resort to the last two steps in the process.
First, if one of the functions is a template specialization and the other one is not, the non-template one is preferred; not applicable here.
Last, it looks at the templates from which the two specialization declarations were synthesized; if one of the templates is more specialized than the other according to the partial ordering of function templates, then the corresponding specialization is preferred. (This is the only place in the process where the original templates come back into play.)
The description below is not very accurate and skips quite a few details, but I'm trying to concentrate on the parts that are relevant to this case. Very roughly:
First, references and cv-qualifiers are stripped from the function parameter declarations of both templates, yielding:
F1(M , const DT<T1, T>*, T1<T>)
F2(G<T2<U>, V>, const DT<T2, U>*, T2<U>)(template parameter names changed to avoid confusion)
Then, deduction is attempted as if for a call to one template using the forms of the function parameters of the other template as arguments, and then the other way around. In this case, the last two pairs of corresponding parameters have identical forms, so deduction succeeds both ways. For the first pair of corresponding parameters:
- Deducing
M
from an argument of the formG<T2<U>, V>
works;M
is deduced asG<T2<U>, V>
. - Deducing
T2
,U
andV
inG<T2<U>, V>
from an argument of the formM
doesn't work (M
can be anything).
In other words,
G<T2<U>, V>
is a "more specific" form thanM
; it cannot represent all the types thatM
can represent; this is the intuitive meaning that more specialized is trying to formalize in this context.- Deducing
So, deduction works for all pairs of corresponding parameters from
F2
toF1
, but not the other way around. This makesF2
more specialized thanF1
in terms of partial ordering.
This means that the specialization corresponding to the second template is preferred in overload resolution.
Related Topics
Parameter Name Omitted, C++ VS C
Strange Ambiguous Call to Overloaded Function Error
Shared_From_This Causing Bad_Weak_Ptr
What Is Assignment via Curly Braces Called? and Can It Be Controlled
Use Visual Studio 2012 and Compile with Older Platform Toolset
How to Brace-Initialize an Std::Array of Std::Pairs
How to Find a Particular Value in an Array and Return Its Index
What Are Use Cases for Structured Bindings
When Do Programmers Use Empty Base Optimization (Ebo)
How to Print Member Function Address in C++
Programmatically Access CPU Fan on a Laptop? (Windows)
How to Sort a Linked List Using Bubble-Sort
How to Break Shared_Ptr Cyclic Reference Using Weak_Ptr
Right Shift and Signed Integer