在不添加类型转换或删除重载函数的情况下解决重载函数的歧义
To solve ambiguity of overloaded function without either adding typecasting or remove the overloaded functions
我做了一个classDummy
,它只是原始类型double
的包装器。 class 的目的是在我介绍另一个 class 替代 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);
}
报告:
<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)
如果我添加类型转换运算符:
operator double(){
return content;
}
不知何故它只能在 Visual Studio 下工作,而不是 g++ 9.3.0,这是我的目标编译器。
使用g++9.3.0编译时,报如下错误:
我已经阅读了资料here,不幸的是我无法在这种情况下删除重载函数。我也不能添加类型转换,因为它对我的目的没有意义。
我也查了here,但是我对模板不是很熟悉。因此我的问题是:
我可以在不添加类型转换或删除重载函数的情况下消除 class 中重载函数的歧义吗?
您显示的Dummy
class只能转换为long int
,但fabs()
不接受long int
,它接受[=17] =]、double
或 long double
。由于 long int
可隐式转换为 float
和 double
,在您添加 double
转换运算符之前,调用是不明确的。
如果您不想这样做,则必须明确说明要调用 fabs()
的哪个重载。通过:
转换 Dummy
转换的结果:
double aa = fabs(static_cast<double>(a));
assigning/casting fabs()
到所需签名的函数指针:
double (*fabs_ptr)(double) = fabs;
fabs_ptr(a);
using fabs_ptr = double (*)(double);
static_cast<fabs_ptr>(fabs)(a);
我做了一个classDummy
,它只是原始类型double
的包装器。 class 的目的是在我介绍另一个 class 替代 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);
}
报告:
<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)
如果我添加类型转换运算符:
operator double(){
return content;
}
不知何故它只能在 Visual Studio 下工作,而不是 g++ 9.3.0,这是我的目标编译器。
使用g++9.3.0编译时,报如下错误:
我已经阅读了资料here,不幸的是我无法在这种情况下删除重载函数。我也不能添加类型转换,因为它对我的目的没有意义。
我也查了here,但是我对模板不是很熟悉。因此我的问题是:
我可以在不添加类型转换或删除重载函数的情况下消除 class 中重载函数的歧义吗?
您显示的Dummy
class只能转换为long int
,但fabs()
不接受long int
,它接受[=17] =]、double
或 long double
。由于 long int
可隐式转换为 float
和 double
,在您添加 double
转换运算符之前,调用是不明确的。
如果您不想这样做,则必须明确说明要调用 fabs()
的哪个重载。通过:
转换
Dummy
转换的结果:double aa = fabs(static_cast<double>(a));
assigning/casting
fabs()
到所需签名的函数指针:double (*fabs_ptr)(double) = fabs; fabs_ptr(a);
using fabs_ptr = double (*)(double); static_cast<fabs_ptr>(fabs)(a);