我有一个自定义的二维点类型,它有一个模板转换运算符:
struct MyPoint
{
double x, y;
template < typename T >
operator T() const
{
return T{ x, y };
}
};
对于 std
类型一切正常:
auto p1 = MyPoint{ 1, 2 };
auto p2 = static_cast< std::array< double, 2 > >( p1 );
auto p3 = static_cast< std::pair< double, double > >( p1 );
但是如果我用 QPointF
尝试同样的事情,我会得到这个错误(使用 g++ v4.8):
../CppTest/main.cpp:23:42: error: call of overloaded 'QPointF(MyPoint&)' is ambiguous
auto p3 = static_cast< QPointF >( p1 );
^
../CppTest/main.cpp:23:42: note: candidates are:
In file included from /usr/include/qt5/QtCore/QPointF:1:0,
from ../CppTest/main.cpp:2:
/usr/include/qt5/QtCore/qpoint.h:270:18: note: constexpr QPointF::QPointF(const QPoint&)
Q_DECL_CONSTEXPR inline QPointF::QPointF(const QPoint &p) : xp(p.x()), yp(p.y()) { }
^
/usr/include/qt5/QtCore/qpoint.h:205:46: note: constexpr QPointF::QPointF(const QPointF&)
class Q_CORE_EXPORT QPointF
^
/usr/include/qt5/QtCore/qpoint.h:205:46: note: constexpr QPointF::QPointF(QPointF&&)
好像编译器甚至没有尝试使用强制转换运算符。如果我改成隐式转换,比如:
QPointF p3 = p1;
它工作正常。如果我使用 QPoint
它也有效 - 它似乎只是 QPointF
导致了问题,我不知道为什么。
最佳答案
据我所知,问题是 QPointF
提供了一个采用 QPoint
的构造函数。
当您执行 static_cast
时,编译器会尝试调用 QPointF(MyPoint&)
,它会看到两种从 MyPoint< 创建
:QPointF
的方法
- 首先将
MyPoint
转换为QPoint
,使用带有QPoint
的构造函数 - 通过首先将
MyPoint
转换为QPointF
,使用任何接受QPointF
的现有构造函数。
因为有不止一种选择,所以它是不明确的。
复制初始化之所以有效,是因为 p1
首先转换为 QPointF
,然后调用复制构造函数。
讨论了 QPointF p(...)
和 QPointF p = ...
之间的区别 here .
为了说明这一点,下面是一个展示相同问题的小例子:
#include <iostream>
struct MyType
{
template < typename T >
operator T() const
{
return T{};
}
};
struct A
{
A() {}
A(const A &) {}
};
struct B
{
B() {}
B(const A &) {}
B(const B &) {}
};
int main()
{
auto my = MyType{};
auto a1 = static_cast<A>(my);
//auto b1 = static_cast<B>(my); // fails
B b2 = my;
}
关于c++ - T 为 QPointF 时的模板转换运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30952303/