T为QPointF时的模板转换运算符

时间:2015-06-20 09:16:21

标签: c++ qt templates casting

我有一个自定义的二维点类型,它有一个模板转换操作符:

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导致问题,我不知道为什么。

1 个答案:

答案 0 :(得分:3)

据我所知,问题是QPointF提供了一个QPoint的构造函数。 当您执行static_cast编译器尝试调用QPointF(MyPoint&)时,它会看到两种方法从QPointF创建MyPoint

  • 使用QPoint构造函数,首先将MyPoint转换为QPoint
  • 首先将QPointF转换为MyPoint,然后使用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;
}