Как написать шаблонную функцию, которая может получить подстроку QString или std :: string? - PullRequest
0 голосов
/ 01 января 2019

Я хотел бы написать шаблонную функцию, которая может обрабатывать как QString, так и std::string, чтобы уменьшить количество копируемого кода.К сожалению, QString не реализует функцию-член substr.QString::mid(int, int) похоже на аналог Qt.Как лучше всего справиться с этим расхождением?Ниже приведена функция, которая должна действовать на объекты типа std :: string:

Функция шаблона:

template <typename StringType>
void do_something(StringType s, StringType::size_type start, StringType::size_type length) {
    // Not defined if StringType == QString
    StringType sub_s = s.substr(start, length);

    // Do something with the substring, for instance:
    std::cout << "Length of substring is " << sub_s.length() << std::endl;
}

Я предполагаю, что мне понадобитсясоздайте другую функцию get_substr, которая определена для std::string и QString, которую я могу вызвать в do_something, но я не уверен, является ли это идеальным решением.

Ответы [ 2 ]

0 голосов
/ 02 января 2019

На момент написания этого полного ответа пользователь zett42 дал правильное решение вашей проблемы.Мне потребовалось некоторое время, чтобы правильно установить Qt и интегрировать его в Visual Studio 2017, так как теперь, когда он у меня работает, я наконец-то смог правильно собрать и скомпилировать свой код, чтобы убедиться, что он работает без каких-либо проблем или ошибок.,

Я думаю, что самое простое, что можно сделать, это использовать функцию QString toStdString().Вы можете написать все свои функции с версией std::string по умолчанию, а затем просто специализировать перегруженную версию QString, которая просто вызывает версию std::string, преобразовав содержимое QString в std::string.Я буду использовать простую функцию printString(), чтобы продемонстрировать это самым простым способом;Вы можете воспользоваться этим подходом и расширить его отсюда.

#include <string>
#include <iostream>
#include <QString>

// defaulted std::string version (full implementation of function)
template <typename StringType>
void printString(const StringType& s) {
    std::cout << s << '\n';
}

// specialized overloaded QString version (it calls the std::string version)
template<>
void printString<QString>(const QString& s ) {
    printString(s.toStdString());
}

int main() {
    const std::string str( "I am an original std::string" );
    const QString qStr( "I am a QString converted to a std::string" );

    printString(str);
    printString(qStr);

    return 0;
}

-Output-

I am an original std::string
I am a QString converted to a std::string

Я думаю, что это самый простой способ достичь того, кем вы являетесьпросить.Это также имеет то преимущество, что если вам нужно внести изменения в вашу реализацию, вам нужно всего лишь изменить версию std::string.

0 голосов
/ 01 января 2019

Оба std::string и QString имеют data() и size() членов, так что вы можете создать std::basic_string_view для унифицированных строковых операций:

#include <iostream>
#include <string_view>

template <typename StringType>
void do_something( StringType const& s, typename StringType::size_type start, typename StringType::size_type length ) 
{   
    std::basic_string_view sv( s.data(), s.size() );

    auto sub_s = sv.substr( start, length );

    // Do something with the substring, for instance:
    std::cout << "Length of substring is " << sub_s.length() << std::endl;
}

Демонстрационная версия

...