Search code examples
c++qttemplatesstdstringqstring

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


I'd like to write a template function that can handle both QString and std::string in order to reduce copied code. Unfortunately, QString does not implement the substr member function. QString::mid(int, int) seems to be the Qt analogue. What is the best way to handle this discrepancy? Below is the function I have that should act on std::string-like objects:

Template function:

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;
}

My guess is that I will need to create another function get_substr that is defined for both std::string and QString, which I can call in do_something, but I am not sure if this is the ideal solution.


Solution

  • Both std::string and QString have data() and size() members, so you could construct a std::basic_string_view for unified string operations:

    #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