I made a class Dummy
, which is just a wrapper of primitive type double
. The purpose of the class is to test potential problems before I introduce another class that substitutes the double
class.
Dummy.h:
class Dummy{
private:
double content;
public:
Dummy(double _content) :content{ _content } {};
operator long int() {return (long int)content;};
}
test.cpp:
#include <math.h>
int main(){
Dummy a = Dummy(1.1);
double aa = fabs(a);
}
It reports:
<source>:17:27: error: call of overloaded 'fabs(Dummy&)' is ambiguous
17 | std::cout << std::fabs(foo);
| ~~~~~~~~~^~~~~ In file included from /usr/include/features.h:461,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/x86_64-linux-gnu/bits/os_defines.h:39,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/x86_64-linux-gnu/bits/c++config.h:586,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/cmath:41,
from <source>:1: /usr/include/x86_64-linux-gnu/bits/mathcalls.h:162:1: note: candidate:
'double fabs(double)'
162 | __MATHCALLX (fabs,, (_Mdouble_ __x),
(__const__));
| ^~~~~~~~~~~ In file included from <source>:1: /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/cmath:241:3:
note: candidate: 'constexpr float std::fabs(float)'
241 |
fabs(float __x)
| ^~~~ /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/cmath:245:3:
note: candidate: 'constexpr long double std::fabs(long double)'
245 | fabs(long double __x)
If I add a type conversion operator:
operator double(){
return content;
}
It somehow only works under Visual Studio, not g++ 9.3.0, which is my target compiler.
During the compiling with g++ 9.3.0, the following errors are reported:
I have read the information here, unfortunately I can't remove the overloaded functions in this case. Neither can I add typecasting, because it doesn't make sense for my purpose.
I also check here, but I am not so familiar with templates. Hence my question is:
Can I eliminate the ambiguity of overloaded function within the class, without adding typecasting, or removing the overloaded functions?
The Dummy
class you have shown is only convertible to long int
, but fabs()
does not accept long int
, it accepts either float
, double
, or long double
. Since long int
is implicitly convertible to float
and double
, the call was ambiguous until you added the double
conversion operator.
If you don't want to do that, then you have to be explicit about which overload of fabs()
you want to call. Either by:
casting the result of the Dummy
conversion:
double aa = fabs(static_cast<double>(a));
assigning/casting fabs()
to a function pointer of the desired signature:
double (*fabs_ptr)(double) = fabs;
fabs_ptr(a);
using fabs_ptr = double (*)(double);
static_cast<fabs_ptr>(fabs)(a);