如何编写可以获取 QString 或 std::string 的子字符串的模板函数?

How do write template function that can get a substring of a QString or a std::string?

我想编写一个可以同时处理 QStringstd::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::stringQString 定义的,我可以在 do_something 中调用它,但是我不确定这是否是理想的解决方案。

std::stringQString都有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;
}

Live Demo

截至撰写此完整答案时,用户 zett42 已为您的问题提供了有效的解决方案。我花了一些时间来正确安装 Qt 并将其集成到 Visual Studio 2017 中,因为现在我可以使用它了,我现在终于能够正确构建和编译我的代码以确保它可以正常工作没有任何问题或错误。

我认为最简单的做法是使用 QStringtoStdString() 函数。您可以使用默认 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;
}

-输出-

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

我认为这是实现您的要求的最简单方法。这还有一个好处,如果您必须对您的实现进行修改,您只需更改 std::string 版本。