2016-09-27 3 views
0

Вслед за большой answer, я пытаюсь получить вокруг -apparanently здравых ошибок **C2536 : cannot specify explicit initializer for arrays** для линии in line: QLineEdit * edits[3] = {&lineEditName, &lineEditGender, &lineEditRegion};Невозможно указать явный инициализатор для массивов в ОСАХ Windows Qt 5.7 (C++)

Я прочитал другие решения (например, 1, 2), но, как представляется, не применяются в моем случае. Я использую Qt Creator 4.1.0 с Qt 5.7.0, MSVC 2013 в Windows с C++. Любые предложения приветствуются.

На дополнительной ноте, и в интересах лучшего понимания Qt с C++, может кто-то момент к другим - вместо использования массивов - для проведения новых разобранных результатов JSon?

Ниже вы можете увидеть полный код из этого ответа (то строка в mainwindow.h):

main.cpp

// https://github.com/KubaO/stackoverflown/tree/master/questions/into-mainwin-39643510 
#include "mainwindow.h" 
#include "controller.h" 

int main(int argc, char *argv[]) 
{ 
    QApplication app{argc, argv}; 
    MainWindow ui; 
    Controller ctl; 
    QTimer timer; 
    timer.start(5*1000); 
    QObject::connect(&timer, &QTimer::timeout, &ctl, &Controller::get); 

    QObject::connect(&ctl, &Controller::busy, &ui, [&]{ ui.setState(MainWindow::Loading); }); 
    QObject::connect(&ui, &MainWindow::request, &ctl, &Controller::get); 
    QObject::connect(&ctl, &Controller::error, &ui, [&]{ ui.setState(MainWindow::Error); }); 
    QObject::connect(&ctl, &Controller::values, &ui, &MainWindow::setFields); 
    ui.show(); 
    return app.exec(); 

controller.h

#ifndef CONTROLLER_H 
#define CONTROLLER_H 

#include <QtNetwork> 

class Controller : public QObject { 
    Q_OBJECT 
    QNetworkAccessManager manager{this}; 
    QNetworkRequest request; 
    Q_SLOT void onReply(QNetworkReply *); 
public: 
    explicit Controller(QObject * parent = nullptr); 
    Q_SLOT void get(); 
    Q_SIGNAL void busy(); 
    Q_SIGNAL void error(const QString &); 
    Q_SIGNAL void values(const QString & name, const QString & gender, const QString & region); 
}; 

#endif // CONTROLLER_H 

контроллер. cpp

#include "controller.h" 

Controller::Controller(QObject *parent) : QObject(parent) 
{ 
    QUrlQuery query; 
    query.addQueryItem("amount", "1"); 
    query.addQueryItem("region", "United States"); 
    QUrl url("http://uinames.com/api/"); 
    url.setQuery(query); 
    request = QNetworkRequest(url); 
    connect(&manager, &QNetworkAccessManager::finished, this, &Controller::onReply); 
} 

void Controller::onReply(QNetworkReply * reply) { 
    if (reply->error() != QNetworkReply::NoError) { 
     emit error(reply->errorString()); 
     manager.clearAccessCache(); 
    } else { 
     //parse the reply JSON and display result in the UI 
     auto jsonObject = QJsonDocument::fromJson(reply->readAll()).object(); 
     auto fullName = jsonObject["name"].toString(); 
     fullName.append(" "); 
     fullName.append(jsonObject["surname"].toString()); 
     emit values(fullName, jsonObject["gender"].toString(), jsonObject["region"].toString()); 
    } 
    reply->deleteLater(); 
} 

void Controller::get() { 
    emit busy(); 
    manager.get(request); 
} 

mainwindow.h

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QtWidgets> 

class MainWindow : public QWidget { 
    Q_OBJECT 
    QFormLayout layout{this}; 
    QLineEdit lineEditName; 
    QLineEdit lineEditGender; 
    QLineEdit lineEditRegion; 
    QPushButton button{"Get Name"}; 
    QLineEdit * edits[3] = {&lineEditName, &lineEditGender, &lineEditRegion}; 
public: 
    enum State { Normal, Loading, Error }; 
    explicit MainWindow(QWidget * parent = nullptr); 
    Q_SLOT void setFields(const QString & name, const QString & gender, const QString & region); 
    Q_SLOT void setState(State); 
    Q_SIGNAL void request(); 
}; 

#endif // MAINWINDOW_H 

mainwindow.cpp

#include "mainwindow.h" 

MainWindow::MainWindow(QWidget *parent) : QWidget(parent) 
{ 
    for(auto edit : edits) edit->setReadOnly(true); 
    layout.addRow("Name:", &lineEditName); 
    layout.addRow("Gender:", &lineEditGender); 
    layout.addRow("Region:", &lineEditRegion); 
    layout.addRow(&button); 
    connect(&button, &QPushButton::clicked, this, &MainWindow::request); 
} 

void MainWindow::setFields(const QString & name, const QString & gender, const QString & region) { 
    setState(Normal); 
    lineEditName.setText(name); 
    lineEditGender.setText(gender); 
    lineEditRegion.setText(region); 
} 

void MainWindow::setState(MainWindow::State state) { 
    if (state == Normal) { 
     for (auto edit : edits) edit->setEnabled(true); 
     button.setEnabled(true); 
    } 
    else if (state == Loading) { 
     for (auto edit : edits) edit->setEnabled(false); 
     button.setEnabled(false); 
    } 
    else if (state == Error) { 
     for (auto edit : edits) edit->setText("Error..."); 
     button.setEnabled(true); 
    } 
} 
+0

W hat if: QLineEdit * edits [] {& lineEditName, & lineEditGender, & lineEditRegion}; – AlexanderVX

+0

@AlexanderVX No также не решает его, он дает ту же ошибку, что и «массив неизвестного размера, не может использоваться в заявке на основе диапазона». Любые другие предложения или альтернативы для массива 'edits' вообще? –

ответ

1

Проблема заключается в том, что MSVC2013 does not support все C++ 11 функций. Основная проблема здесь заключается в том, что вы не можете указать инициализацию в классе для массивов-членов.

Ближайший обходной путь, на мой взгляд было бы использовать std::array вместо массива C для edits, так как MSVC2013, кажется, поддерживает инициализацию std::array с помощью aggregate initialization, вы можете заменить ваш:

QLineEdit * edits[3] = {&lineEditName, &lineEditGender, &lineEditRegion}; 

использовать std::array и агрегат инициализации, как это:

std::array<QLineEdit*,3> edits{{&lineEditName, &lineEditGender, &lineEditRegion}}; 

Обратите внимание, что вы должны добавить #include <array> к вашему mainwindow.h для использования std::array.

На дополнительной ноте, и в интересах лучшего понимания Qt с C++, может кто-то точке на другой путь -instead использования arrays- для проведения новых разобранные результатов JSon?

Вы не используете массивов для проведения новых разобранных результатов JSon, это просто, как вы используете QJsonObject.

Если вы ищете способ дальнейшего раздельного анализа JSON в своем классе. Возможно, вам понадобится некоторый класс (например.NameData), который инкапсулирует данные имени (fullName, gender, region) и предоставляет способ построения из данных JSON QByteArray.

Этот способ класс Controller ничего не знает о JSON, он просто использует класс NameData для анализа ответа, который он имеет в сети.

вы можете реализовать это следующим образом:

namedata.h

#ifndef NAMEDATA_H 
#define NAMEDATA_H 

#include <QtCore> 

class NameData 
{ 
public: 
    QString fullName; 
    QString gender; 
    QString region; 

    static NameData fromReplyByteArray(QByteArray byteArray); 
}; 

#endif // NAMEDATA_H 

namedata.cpp

#include "namedata.h" 

NameData NameData::fromReplyByteArray(QByteArray byteArray){ 
    QJsonObject jsonObject = QJsonDocument::fromJson(byteArray).object(); 
    NameData result; 
    result.fullName = jsonObject["name"].toString(); 
    result.fullName.append(" "); 
    result.fullName.append(jsonObject["surname"].toString()); 
    result.gender= jsonObject["gender"].toString(); 
    result.region= jsonObject["region"].toString(); 
    return result; 
} 

Теперь onReply функция Controller класса, должно быть:

void Controller::onReply(QNetworkReply * reply) { 
    if (reply->error() != QNetworkReply::NoError) { 
     emit error(reply->errorString()); 
     manager.clearAccessCache(); 
    } else { 
     //parse the reply JSON and display result in the UI (using the separate class) 
     NameData nameData= NameData::fromReplyByteArray(reply->readAll()); 
     emit values(nameData.fullName, nameData.gender, nameData.region); 
    } 
    reply->deleteLater(); 
}