当我使用g++ 5.1编译您的程序时,我得到以下结果:
/home/imk/develop/so/mpf_cast/main.cpp:35:25: error: call of overloaded ‘__gmp_expr(q&)’ is ambiguous
cout << (mpf_class) x << endl;
^
/home/imk/develop/so/mpf_cast/main.cpp:35:25: note: candidates are:
In file included from /home/imk/develop/so/mpf_cast/main.cpp:2:0:
/usr/include/gmpxx.h:1883:3: note: __gmp_expr<__mpf_struct [1], __mpf_struct [1]>::__gmp_expr(double)
__gmp_expr(double d) { mpf_init_set_d(mp, d); }
^
/usr/include/gmpxx.h:1880:3: note: __gmp_expr<__mpf_struct [1], __mpf_struct [1]>::__gmp_expr(float)
__gmp_expr(float f) { mpf_init_set_d(mp, f); }
^
/usr/include/gmpxx.h:1876:3: note: __gmp_expr<__mpf_struct [1], __mpf_struct [1]>::__gmp_expr(long unsigned int)
__gmp_expr(unsigned long int l) { mpf_init_set_ui(mp, l); }
^
/usr/include/gmpxx.h:1873:3: note: __gmp_expr<__mpf_struct [1], __mpf_struct [1]>::__gmp_expr(long int)
__gmp_expr(signed long int l) { mpf_init_set_si(mp, l); }
^
/usr/include/gmpxx.h:1869:3: note: __gmp_expr<__mpf_struct [1], __mpf_struct [1]>::__gmp_expr(short unsigned int)
__gmp_expr(unsigned short int s) { mpf_init_set_ui(mp, s); }
^
/usr/include/gmpxx.h:1866:3: note: __gmp_expr<__mpf_struct [1], __mpf_struct [1]>::__gmp_expr(short int)
__gmp_expr(signed short int s) { mpf_init_set_si(mp, s); }
^
/usr/include/gmpxx.h:1862:3: note: __gmp_expr<__mpf_struct [1], __mpf_struct [1]>::__gmp_expr(unsigned int)
__gmp_expr(unsigned int i) { mpf_init_set_ui(mp, i); }
^
/usr/include/gmpxx.h:1859:3: note: __gmp_expr<__mpf_struct [1], __mpf_struct [1]>::__gmp_expr(int)
__gmp_expr(signed int i) { mpf_init_set_si(mp, i); }
^
/usr/include/gmpxx.h:1855:3: note: __gmp_expr<__mpf_struct [1], __mpf_struct [1]>::__gmp_expr(unsigned char)
__gmp_expr(unsigned char c) { mpf_init_set_ui(mp, c); }
^
/usr/include/gmpxx.h:1852:3: note: __gmp_expr<__mpf_struct [1], __mpf_struct [1]>::__gmp_expr(signed char)
__gmp_expr(signed char c) { mpf_init_set_si(mp, c); }
^
/usr/include/gmpxx.h:1837:3: note: __gmp_expr<__mpf_struct [1], __mpf_struct [1]>::__gmp_expr(const __gmp_expr<__mpf_struct [1], __mpf_struct [1]>&)
__gmp_expr(const __gmp_expr &f)
^
问题转换表达式
(mpf_class) x
需要从
q
构造一个
mpf_class
(
typedef __gmp_expr<mpf_t, mpf_t> mpf_class
)。因此,您可以考虑
q x(1);
mpf_class m(x);
这是什么引起了相同的诊断结果。
为什么构造函数不明确?因为:
- 当然,不存在名为
mpf_class(q const &)
的构造函数
- 因此,如果存在从
q
到在诊断中枚举的11种其他类型之一的转换,则需要进行转换,以便可以构造出一个mpf_class
。
- 但是,由于您提供了两个强制转换运算符,因此有两种这样的转换方法,每种都很好。
转换operator double()
可以满足11个构造函数中的第一个,而operator mpf_class()
可以满足最后一个。编译器没有选择任何一个构造函数的依据。
如果您牺牲其中一个强制转换运算符,问题将会消失。如果您必须同时拥有它们两个,则可以通过使它们两个都成为explicit
来解决问题,这样编译器就不会考虑调用转换,除非它被显式调用:
explicit operator double()
{
return (double)i;
}
explicit operator mpf_class()
{
return (mpf_class)i;
}
然后你会发现,例如:
int main()
{
q x(1);
mpf_class mpf(x);
double d(x);
d = static_cast<double>(q(2));
mpf = static_cast<mpf_class>(q(2));
return 0;
}
顺便提一下:
- 强制类型转换操作符应该是
const
- 在函数内部,当存在隐式转换时,将返回值强制转换为返回类型是多余的。
因此:
explicit operator double() const
{
return i;
}
explicit operator mpf_class() const
{
return i;
}
mpf_class
是如何定义的?它是什么? - user35443