Qt5: ошибка компиляции во время QSharedPointer::Создайте() - PullRequest
0 голосов
/ 16 мая 2018

Ожидается ли, что QSharedPointer :: create () не будет работать или это ошибка?Я получаю сообщение об ошибке:

/usr/include/qt5/QtCore/qsharedpointer_impl.h:439:9: error: 
invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
new (result.data()) T(std::forward<Args>(arguments)...);

приведение из неконстантного общего указателя и конструктора из необработанного константного указателя.

Я получил это для Qt5.7.0 и Qt5.10.0.

Вот минимальный пример:

#include <QSharedPointer>

struct A {};

int main(int argc, char *argv[])
{
    auto ca = QSharedPointer<const A>::create();
    return 0;
}

Вот один пример файла (не минимальный), но снесколько рабочих случаев, 2 не работает и отладка.Комментируемые определения предназначены для «не компилируемых» частей.

#include <QSharedPointer>
#include <QDebug>

#define FROM_PTR
//#define CONST_CREATE
#define FROM_RAW_PTR
#define PERFECT_FORWARD_CREATE
//#define PERFECT_FORWARD_CREATE_CONST
#define BUILTIN_CAST


class A
{
public:
    A() = default;
    A(int i) : _i{i} {}
    void foo() const { qDebug() << "const foo" << _i; }
    void foo() {  qDebug() << "foo" << ++_i; }

private:
    int _i{0};

};

using ASPtr = QSharedPointer<A>;
using ASCPtr = QSharedPointer<const A>;


int main(int argc, char *argv[])
{
    Q_UNUSED(argc)
    Q_UNUSED(argv)

#ifdef FROM_PTR
    qDebug() << "FROM_PTR";
    auto a1 = ASPtr::create();
    a1->foo();

    auto ca1 = static_cast<ASCPtr>(a1);
    ca1->foo();
    qDebug() << "\n";
#endif // FROM_PTR


#ifdef CONST_CREATE
    qDebug() << "CONST_CREATE";
    auto ca2 = ASCPtr::create();
    ca2->foo();
    qDebug() << "\n";
#endif // CONST_CREATE


#ifdef FROM_RAW_PTR
    qDebug() << "FROM_RAW_PTR";
    auto ca3 = ASCPtr(new const A);
    ca3->foo();
    qDebug() << "\n";
#endif // FROM_RAW_PTR


#ifdef PERFECT_FORWARD_CREATE
    qDebug() << "PERFECT_FORWARD_CREATE";
    auto a2 = ASPtr::create(10);
    a2->foo();
    qDebug() << "\n";
#endif //  PERFECT_FORWARD_CREATE


#ifdef PERFECT_FORWARD_CREATE_CONST
    qDebug() << "PERFECT_FORWARD_CREATE_CONST";
    auto ca4 = ASCPtr::create(20);
    ca4->foo();
    qDebug() << "\n";
#endif //  PERFECT_FORWARD_CREATE


#ifdef BUILTIN_CAST
    qDebug() << "BUILTIN_CAST";
    QSharedPointer<A> a3 = ASPtr::create();
    a3->foo();

    auto ca4 = a3.constCast<const A>();
    ca4->foo();
    qDebug() << "\n";
#endif // BUILTIN_CAST


    return 0;
}

1 Ответ

0 голосов
/ 16 мая 2018

Это известная ошибка Qt ( QTBUG-49748 ). Хотя он отмечен как исправленный в Qt 5.6.0, ошибка все еще присутствует, как указано в комментариях.

Почему это происходит?

Посмотрите на реализацию класса QSharedPointer qsharedpointer_impl.h .

В частности, строка:

new (result.data()) T(std::forward<Args>(arguments)...);

использует result.data () в качестве нового выражения параметры размещения . К сожалению, можно не использовать указатель const в качестве параметра размещения (подробнее см. этот вопрос здесь, в SO).

Следовательно, вы ничего не можете сделать, кроме как сообщать об этом разработчикам Qt через официальный трекер ошибок.

Вы можете взглянуть на интеллектуальные указатели, предоставляемые стандартной библиотекой (например, std :: shared_ptr ), если вы не обязаны использовать Qt.

UPDATE

Как сообщалось в Qt bug tracker, эта ошибка была исправлена ​​ в версии 5.11 ( здесь - это связанный коммит). В основном они использовали std :: remove_cv , чтобы удалить самый верхний констант из указанного типа.

...