компилятор
clang version 12.0.0
Target: x86_64-pc-windows-msvc
struct FrameStyle
{
QColor color; // has both == and != operators
Qt::PenStyle penStyle; // enum
Distance padding; // has == operator
bool operator==(const FrameStyle& other)
{
return other.color == color
&& other.penStyle == penStyle
&& other.padding == padding;
}
};
FrameStyle style;
FrameStyle m_prevStyle;
const bool styleChanged = !(style == m_prevStyle); // ok
const bool styleChanged = style != m_prevStyle; // Invalid operands to binary expression ('FrameStyle' and 'FrameStyle')
error: invalid operands to binary expression ('gns::FrameStyle' and 'gns::FrameStyle')
const bool styleChanged = style != m_prevStyle;
~~~~~ ^ ~~~~~~~~~~~
E:\5.15.8\msvc\include\QtCore/qchar.h(62,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'char' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(char lhs, QLatin1Char rhs) noexcept { return lhs != rhs.toLatin1(); }
^
E:\5.15.8\msvc\include\QtCore/qchar.h(69,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QLatin1Char' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(QLatin1Char lhs, char rhs) noexcept { return lhs.toLatin1() != rhs; }
^
E:\5.15.8\msvc\include\QtCore/qchar.h(640,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QChar' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(QChar c1, QChar c2) noexcept { return !operator==(c1, c2); }
^
E:\5.15.8\msvc\include\QtCore/qchar.h(651,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QChar' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(QChar lhs, std::nullptr_t) noexcept { return !operator==(lhs, nullptr); }
^
E:\5.15.8\msvc\include\QtCore/qchar.h(656,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(std::nullptr_t, QChar rhs) noexcept { return !operator==(nullptr, rhs); }
^
E:\5.15.8\msvc\include\QtCore/qbytearray.h(690,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QByteArray' for 1st argument
inline bool operator!=(const QByteArray &a1, const QByteArray &a2) noexcept
^
E:\5.15.8\msvc\include\QtCore/qbytearray.h(692,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QByteArray' for 1st argument
inline bool operator!=(const QByteArray &a1, const char *a2) noexcept
^
E:\5.15.8\msvc\include\QtCore/qbytearray.h(694,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const char *' for 1st argument
inline bool operator!=(const char *a1, const QByteArray &a2) noexcept
^
E:\5.15.8\msvc\include\QtCore/qbytearray.h(811,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QByteArray::FromBase64Result' for 1st argument
inline bool operator!=(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1379,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QString::Null' for 1st argument
inline bool operator!=(QString::Null, QString::Null) { return false; }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1381,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QString::Null' for 1st argument
inline bool operator!=(QString::Null, const QString &s) { return !s.isNull(); }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1383,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QString' for 1st argument
inline bool operator!=(const QString &s, QString::Null) { return !s.isNull(); }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1388,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QLatin1String' for 1st argument
inline bool operator!=(QLatin1String s1, QLatin1String s2) noexcept
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1432,32): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const char *' for 1st argument
inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, const QString &s2)
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1445,32): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const char *' for 1st argument
inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, QLatin1String s2)
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1822,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QStringRef' for 1st argument
inline bool operator!=(const QStringRef &s1, const QStringRef &s2) noexcept
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1834,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QString' for 1st argument
inline bool operator!=(const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) != 0; }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1841,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QStringRef' for 1st argument
inline bool operator!=(const QStringRef &lhs, const QString &rhs) noexcept { return rhs != lhs; }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1870,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QLatin1String' for 1st argument
inline bool operator!=(QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) != 0; }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1877,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QStringRef' for 1st argument
inline bool operator!=(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs != lhs; }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1891,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QChar' for 1st argument
inline bool operator!=(QChar lhs, const QString &rhs) noexcept { return !(lhs == rhs); }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1896,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QString' for 1st argument
inline bool operator!=(const QString &lhs, QChar rhs) noexcept { return !(rhs == lhs); }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1910,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QChar' for 1st argument
inline bool operator!=(QChar lhs, const QStringRef &rhs) noexcept { return !(lhs == rhs); }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1915,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QStringRef' for 1st argument
inline bool operator!=(const QStringRef &lhs, QChar rhs) noexcept { return !(rhs == lhs); }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1929,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QChar' for 1st argument
inline bool operator!=(QChar lhs, QLatin1String rhs) noexcept { return !(lhs == rhs); }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1934,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QLatin1String' for 1st argument
inline bool operator!=(QLatin1String lhs, QChar rhs) noexcept { return !(rhs == lhs); }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1942,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QStringView' for 1st argument
inline bool operator!=(QStringView lhs, QStringView rhs) noexcept { return !(lhs == rhs); }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1950,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QStringView' for 1st argument
inline bool operator!=(QStringView lhs, QChar rhs) noexcept { return lhs != QStringView(&rhs, 1); }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1957,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QChar' for 1st argument
inline bool operator!=(QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) != rhs; }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1965,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QStringView' for 1st argument
inline bool operator!=(QStringView lhs, QLatin1String rhs) noexcept { return !(lhs == rhs); }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1972,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QLatin1String' for 1st argument
inline bool operator!=(QLatin1String lhs, QStringView rhs) noexcept { return !(lhs == rhs); }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1981,32): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QStringRef' for 1st argument
inline QT_ASCII_CAST_WARN bool operator!=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) != 0; }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(1988,32): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QByteArray' for 1st argument
inline QT_ASCII_CAST_WARN bool operator!=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) != 0; }
^
E:\5.15.8\msvc\include\QtCore/qstring.h(2010,32): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const char *' for 1st argument
inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, const QStringRef &s2)
^
E:\5.15.8\msvc\include\QtCore/qpoint.h(168,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QPoint' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(const QPoint &p1, const QPoint &p2)
^
E:\5.15.8\msvc\include\QtCore/qpoint.h(363,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QPointF' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(const QPointF &p1, const QPointF &p2)
^
E:\5.15.8\msvc\include\QtCore/qvariant.h(616,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QVariant' for 1st argument
inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2)
^
E:\5.15.8\msvc\include\QtCore/qmetaobject.h(202,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QMetaMethod' for 1st argument
inline bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2)
^
E:\5.15.8\msvc\include\QtCore/qmargins.h(144,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QMargins' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(const QMargins &m1, const QMargins &m2) noexcept
^
E:\5.15.8\msvc\include\QtCore/qmargins.h(380,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QMarginsF' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(const QMarginsF &lhs, const QMarginsF &rhs) noexcept
^
E:\5.15.8\msvc\include\QtCore/qsize.h(178,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QSize' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(const QSize &s1, const QSize &s2) noexcept
^
E:\5.15.8\msvc\include\QtCore/qsize.h(353,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QSizeF' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(const QSizeF &s1, const QSizeF &s2) noexcept
^
E:\5.15.8\msvc\include\QtCore/qrect.h(459,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QRect' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(const QRect &r1, const QRect &r2) noexcept
^
E:\5.15.8\msvc\include\QtCore/qrect.h(866,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QRectF' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(const QRectF &r1, const QRectF &r2) noexcept
^
E:\5.15.8\msvc\include\QtGui/qvector2d.h(216,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QVector2D' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(const QVector2D &v1, const QVector2D &v2)
^
E:\5.15.8\msvc\include\QtGui/qevent.h(877,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'QPointingDeviceUniqueId' for 1st argument
inline bool operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) noexcept
^
C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared/guiddef.h(197,15): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const GUID' (aka 'const _GUID') for 1st argument
__inline bool operator!=(REFGUID guidOne, REFGUID guidOther)
^
E:\5.15.8\msvc\include\QtGui/qvector3d.h(241,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QVector3D' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(const QVector3D &v1, const QVector3D &v2)
^
E:\5.15.8\msvc\include\QtGui/qvector4d.h(241,30): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QVector4D' for 1st argument
Q_DECL_CONSTEXPR inline bool operator!=(const QVector4D &v1, const QVector4D &v2)
^
E:\5.15.8\msvc\include\QtGui/qquaternion.h(289,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QQuaternion' for 1st argument
inline bool operator!=(const QQuaternion &q1, const QQuaternion &q2)
^
E:\5.15.8\msvc\include\QtGui/qsurfaceformat.h(173,19): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QSurfaceFormat' for 1st argument
Q_GUI_EXPORT bool operator!=(const QSurfaceFormat&, const QSurfaceFormat&);
^
E:\5.15.8\msvc\include\QtGui/qcursor.h(130,13): note: candidate function not viable: no known conversion from 'gns::FrameStyle' to 'const QCursor' for 1st argument
inline bool operator!=(const QCursor &lhs, const QCursor &rhs) noexcept { return !(lhs == rhs); }
^
E:\5.15.8\msvc\include\QtCore/qpair.h(118,41): note: candidate template ignored: could not match 'QPair<type-parameter-0-0, type-parameter-0-1>' against 'gns::FrameStyle'
Q_DECL_CONSTEXPR Q_INLINE_TEMPLATE bool operator!=(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2)
^
E:\5.15.8\msvc\include\QtCore/qscopedpointer.h(190,13): note: candidate template ignored: could not match 'QScopedPointer<type-parameter-0-0, type-parameter-0-1>' against 'gns::FrameStyle'
inline bool operator!=(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) noexcept
^
E:\5.15.8\msvc\include\QtCore/qscopedpointer.h(208,13): note: candidate template ignored: could not match 'QScopedPointer<type-parameter-0-0, type-parameter-0-1>' against 'gns::FrameStyle'
inline bool operator!=(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t) noexcept
^
E:\5.15.8\msvc\include\QtCore/qscopedpointer.h(214,13): note: candidate template ignored: could not match 'QScopedPointer<type-parameter-0-0, type-parameter-0-1>' against 'gns::FrameStyle'
inline bool operator!=(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs) noexcept
^
E:\5.15.8\msvc\include\QtCore/qvarlengtharray.h(573,6): note: candidate template ignored: could not match 'QVarLengthArray<type-parameter-0-0, Prealloc>' against 'gns::FrameStyle'
bool operator!=(const QVarLengthArray<T, Prealloc1> &l, const QVarLengthArray<T, Prealloc2> &r)
^
E:\5.15.8\msvc\include\QtCore/qsharedpointer_impl.h(752,6): note: candidate template ignored: could not match 'QSharedPointer<type-parameter-0-0>' against 'gns::FrameStyle'
bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) noexcept
^
E:\5.15.8\msvc\include\QtCore/qsharedpointer_impl.h(768,6): note: candidate template ignored: could not match 'QSharedPointer<type-parameter-0-0>' against 'gns::FrameStyle'
bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2) noexcept
^
E:\5.15.8\msvc\include\QtCore/qsharedpointer_impl.h(773,6): note: candidate template ignored: could not match 'const T *' against 'gns::FrameStyle'
bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2) noexcept
^
E:\5.15.8\msvc\include\QtCore/qsharedpointer_impl.h(784,6): note: candidate template ignored: could not match 'QSharedPointer<type-parameter-0-0>' against 'gns::FrameStyle'
bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2) noexcept
^
E:\5.15.8\msvc\include\QtCore/qsharedpointer_impl.h(796,13): note: candidate template ignored: could not match 'QSharedPointer<type-parameter-0-0>' against 'gns::FrameStyle'
inline bool operator!=(const QSharedPointer<T> &lhs, std::nullptr_t) noexcept
^
E:\5.15.8\msvc\include\QtCore/qsharedpointer_impl.h(808,13): note: candidate template ignored: could not match 'QSharedPointer<type-parameter-0-0>' against 'gns::FrameStyle'
inline bool operator!=(std::nullptr_t, const QSharedPointer<T> &rhs) noexcept
^
E:\5.15.8\msvc\include\QtCore/qsharedpointer_impl.h(820,13): note: candidate template ignored: could not match 'QWeakPointer<type-parameter-0-0>' against 'gns::FrameStyle'
inline bool operator!=(const QWeakPointer<T> &lhs, std::nullptr_t) noexcept
^
E:\5.15.8\msvc\include\QtCore/qsharedpointer_impl.h(832,13): note: candidate template ignored: could not match 'QWeakPointer<type-parameter-0-0>' against 'gns::FrameStyle'
inline bool operator!=(std::nullptr_t, const QWeakPointer<T> &rhs) noexcept
^
E:\5.15.8\msvc\include\QtCore/qpointer.h(114,13): note: candidate template ignored: could not match 'const T *' against 'gns::FrameStyle'
inline bool operator!=(const T *o, const QPointer<T> &p)
^
E:\5.15.8\msvc\include\QtCore/qpointer.h(118,13): note: candidate template ignored: could not match 'QPointer<type-parameter-0-0>' against 'gns::FrameStyle'
inline bool operator!= (const QPointer<T> &p, const T *o)
^
E:\5.15.8\msvc\include\QtCore/qpointer.h(122,13): note: candidate template ignored: could not match 'T *' against 'gns::FrameStyle'
inline bool operator!=(T *o, const QPointer<T> &p)
^
E:\5.15.8\msvc\include\QtCore/qpointer.h(126,13): note: candidate template ignored: could not match 'QPointer<type-parameter-0-0>' against 'gns::FrameStyle'
inline bool operator!= (const QPointer<T> &p, T *o)
^
E:\5.15.8\msvc\include\QtCore/qpointer.h(130,13): note: candidate template ignored: could not match 'QPointer<type-parameter-0-0>' against 'gns::FrameStyle'
inline bool operator!= (const QPointer<T> &p1, const QPointer<T> &p2)
^
1 error generated.
Зачем мне в этом случае перегружать оператор равенства?
Почему я не получаю автоматический не равный оператор?
Таким был C++ с момента его создания... до C++20, в котором были введены сравнения по умолчанию, https://en.cppreference.com/w/cpp/language/default_comparisons.
bool operator==(const FrameStyle& other) const = default; // c++20
(это также обеспечит постоянный operator!=
, насколько я понимаю)
У него интересная предыстория с участием Денниса Ричи (из C), Страуструпа и Степанова.
Некоторые люди беспокоились, что поэлементное равенство будет означать неверную вещь для структур, в которых данные являются косвенными (например, член-указатель в динамическом массиве).
Контраргументом было то, что это несовместимо с operator=
, который обычно предоставляется по умолчанию, и это очень полезно, даже если наивно это означает неправильную вещь.
Я согласен с мнением, что operator=
и operator==
(и operator!=
, и, возможно, многие другие) должны быть предоставлены по умолчанию, и разработчик несет ответственность за изменение их значения при необходимости.
Сказав это, в вашем случае я вижу две проблемы:
bool operator==(const FrameStyle& other) const
Вы определяете перегрузку оператора для
==
, но не для!=
. Это не одни и те же операторы, и до стандарта C++20 они не генерировались автоматически из других.