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

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&),它会看到两种从QPointF创建MyPoint的方法:

  • 使用构造函数获取QPoint,方法是先将MyPoint转换为QPoint,再将
  • 使用任何通过首先将QPointF转换为MyPoint来获取QPointF的现有构造函数。

  • 由于存在多种选择,因此模棱两可。

    复制初始化起作用是因为p1首先转换为QPointF,然后调用复制构造函数。

    here讨论了QPointF p(...)QPointF p = ...之间的区别。

    为了说明这一点,下面是一个展示相同问题的小例子:
    #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/

    10-11 04:17