سؤال

أرغب في استخدام حالة التبديل في برنامجي ولكن المترجم يعطيني هذا الخطأ:

switch expression of type 'QString' is illegal

كيف يمكنني استخدام switch بيان مع أ QString?

قانون بلدي على النحو التالي:

bool isStopWord( QString word )
{
bool flag = false ;

switch( word )
{
case "the":
    flag = true ;
    break ;
case "at" :
    flag = true ;
    break ;
case "in" :
    flag = true ;
    break ;
case "your":
    flag = true ;
    break ;
case "near":
    flag = true ;
    break ;
case "all":
    flag = true ;
    break ;
case "this":
    flag = true ;
    break ;
}

return flag ;
}
هل كانت مفيدة؟

المحلول

كيف يمكنني استخدام بيان التبديل مع سلسلة?

لا يمكنك.في لغة ج language switch لا يمكن استخدام البيان إلا مع أنواع متكاملة أو تعداد.يمكنك وضع كائن من نوع الفئة رسميا في switch بيان ، ولكن هذا يعني ببساطة أن المترجم سيبحث عن تحويل معرف من قبل المستخدم لتحويله إلى نوع متكامل أو تعداد.

نصائح أخرى

يمكنك، إنشاء قائمة Qstring قبل التكرار، مثل هذا: giveacodicetagpre.

ثم: giveacodicetagpre.

لا يمكن التبديل مباشرة على السلاسل في ج++.ومع ذلك فمن الممكن في كيو تي باستخدام QMetaEnum كما هو موضح هنا: Q_ENUM وكيفية التبديل على سلسلة

للقيام بذلك ، أولا أعلن التعداد مع ال سلاسل لاستخدامها في حالات التبديل كاسم العداد في إعلان صفك.ثم أضف التعداد إلى البيانات الوصفية باستخدام Q_ENUMS من أجل البرنامج للبحث في وقت لاحق.

#include <QMetaEnum>

class TestCase : public QObject
{
    Q_OBJECT
    Q_ENUMS(Cases)        // metadata declaration

public:
    explicit Test(QObject *parent = 0);

    enum Cases
    {
        THE, AT, IN, THIS // ... ==> strings to search, case sensitive
    };

public slots:
    void SwitchString(QString word);
};

ثم في .cpp ملف تنفيذ التبديل المطلوب بعد تحويل السلسلة إلى القيمة المقابلة مع .

المقارنة حساسة لحالة الأحرف ، لذا إذا كنت تريد بحثا غير حساس لحالة الأحرف ، فقم بتحويل سلسلة الإدخال إلى الأحرف الكبيرة/الصغيرة أولا.يمكنك أيضا إجراء تحويلات أخرى مطلوبة للسلسلة.على سبيل المثال ، في حال احتجت إلى تبديل السلاسل بمسافات فارغة أو أحرف غير مسموح بها في معرفات ج/ج C ، يمكنك تحويل/إزالة/استبدال هذه الأحرف لجعل السلسلة معرفا صالحا.

void TestCase::SwitchString(QString word)
{
    // get information about the enum named "Cases"
    QMetaObject MetaObject = this->staticMetaObject;
    QMetaEnum MetaEnum = MetaObject.enumerator(MetaObject.indexOfEnumerator("Cases"));

    switch (MetaEnum.keyToValue(word.toUpper().toLatin1()))
    // or simply switch (MetaEnum.keyToValue(word)) if no string modification is needed
    {
        case THE:  /* do something */ break;
        case AT:   /* do something */ break;
        case IN:   /* do something */ break;
        case THIS: /* do something */ break;
        default:   /* do something */ break;
    }
}

ثم مجرد استخدام الطبقة لتبديل السلاسل.على سبيل المثال:

TestCase test;
test.SwitchString("At");
test.SwitchString("the");
test.SwitchString("aBCdxx");

إذا كنت تستطيع استخدام مترجم ج modern الحديث ثم هل يمكن حساب قيمة تجزئة وقت الترجمة لسلاسل الخاص بك.في هذه الإجابة هناك مثال على بسيطة نوعا ما constexpr وظيفة التجزئة.

لذلك يمكن أن يبدو الحل كما يلي:

// function from https://stackoverflow.com/a/2112111/1150303
// (or use some other constexpr hash functions from this thread)
unsigned constexpr const_hash(char const *input) {
    return *input ?
    static_cast<unsigned int>(*input) + 33 * const_hash(input + 1) :
    5381;
}

QString switchStr = "...";
switch(const_hash(switchStr.toStdString().c_str()))
{
case const_hash("Test"):
    qDebug() << "Test triggered";
    break;
case const_hash("asdf"):
    qDebug() << "asdf triggered";
    break;
default:
    qDebug() << "nothing found";
    break;
}

انها لا تزال غير الحل الأمثل.يمكن أن يكون هناك تصادمات التجزئة (وبالتالي اختبار البرنامج الخاص بك كلما قمت بإضافة / تغيير case) وعليك أن تكون حذرا في التحويل من QString إلى char* إذا كنت ترغب في استخدام الغريبة أو utf الشخصيات ، على سبيل المثال.

مقابل 11 دولارا أمريكيا CONFIG += c++11 إلى المشروع الخاص بك ، ل كيو تي 5.كيو تي 4: QMAKE_CXXFLAGS += -std=c++11

@DomTomCat الجواب لمست بالفعل على هذا, ولكن لأن السؤال هو على وجه التحديد يسأل عن Qt, هناك طريقة أفضل.

Qt بالفعل تجزئة وظيفة QStrings ، ولكن للأسف Qt4 هو qHash غير مؤهل كما constexpr.لحسن الحظ Qt هو المصدر المفتوح ، حتى نتمكن من نسخ qHash وظائف QStrings في منطقتنا constexpr تجزئة الوظيفة واستخدام ذلك!

Qt4 هو qHash المصدر

لقد عدلت عليه فقط تحتاج معلمة واحدة (سلسلة حرفية هي دائما خالية منتهية):

uint constexpr qConstHash(const char *string)
{
    uint h = 0;

    while (*string != 0)
    {
        h = (h << 4) + *string++;
        h ^= (h & 0xf0000000) >> 23;
        h &= 0x0fffffff;
    }
    return h;
}

مرة واحدة كنت قد حددت هذا ، يمكنك استخدامها في التبديل البيانات مثل ذلك:

QString string;
// Populate the QString somehow.

switch (qHash(string))
{
    case qConstHash("a"):
        // Do something.
        break;
    case qConstHash("b"):
        // Do something else.
        break;
}

لأن هذا الأسلوب يستخدم نفس الكود Qt يستخدم لحساب التجزئة ، سيكون لها نفس تجزئة الاصطدام المقاومة كما QHash ، الذي هو عادة جيدة جدا.الجانب السلبي هو أن هذا يتطلب إلى حد ما في الآونة الأخيرة مترجم--لأنه قد عدم العودة البيانات في constexpr تجزئة الوظيفة ، فإنه يتطلب C++14.

كما ذكرنا سابقًا، هذه ليست مشكلة كيو تي، يمكن لبيانات التبديل استخدام التعبيرات الثابتة فقط، انظر إلى فئات المجموعة أ QSet هو حل جيد

void initStopQwords(QSet<QString>& stopSet)
{
    // Ideally you want to read these from a file
    stopSet << "the";
    stopSet << "at";
    ...

}

bool isStopWord(const QSet<QString>& stopSet, const QString& word)
{
    return stopSet.contains(word);
}

جرب هذا: giveacodicetagpre.

كيفية استخدام: giveacodicetagpre.

هناك بعض سحر ماكرو بسيط.بعد إعادة التعمير هذا: giveacodicetagpre. سوف تعمل

مثل هذا: giveacodicetagpre.

case "the":
    //^^^ case label must lead to a constant expression

أنا لست على علم qt, ولكن يمكنك أن تجرب ذلك.يمكنك تجنب switch و تستخدم مباشرة == وعلى سبيل المقارنة ، إذا QString لا يختلف عن العادي std::string.

if( word == "the" )
{
   // ..
}
else if( word == "at" )
{
   // ..
}
// ....

يبدو هذا سماو imho قليلا. giveacodicetagpre.

أود أن أقترح استخدامها إذا وكسر.هذا من شأنه أن يجعله بالقرب من التبديل القضية في الحساب. giveacodicetagpre.

هذا لا علاقة له بـ Qt، تمامًا كما لا علاقة له بلون جواربك.

بناء جملة التبديل C++ كما يلي:

char c = getc();
switch( c ) {
case 'a':
    a();
    break;
case 'b':
    b();
    break;
default:
    neither();
}

إذا لم يساعد ذلك، فيرجى إدراج رسالة الخطأ بالتفصيل، مع لون جواربك.

يحرر:للرد على ردك، لا يمكنك استخدام switch مع أنواع غير متكاملة.وعلى وجه الخصوص، لا يمكنك استخدام أنواع الفصول الدراسية.ليست كائنات من النوع QString وليس كائنات من أي نوع آخر.يمكنك استخدام if-else if-else إنشاء بدلاً من ذلك، أو يمكنك استخدام وقت التشغيل أو تعدد أشكال وقت الترجمة، أو التحميل الزائد، أو أي من مجموعة البدائل لـ switch.

تحقق من هذا، فإنه يساعدني giveacodicetagpre.

هو مطابق لبيان التبديل C ++. giveacodicetagpre.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top