Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何编写可以获取QString或std::string的子字符串的模板函数?_C++_Qt_Templates_Stdstring_Qstring - Fatal编程技术网

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

C++ 如何编写可以获取QString或std::string的子字符串的模板函数?,c++,qt,templates,stdstring,qstring,C++,Qt,Templates,Stdstring,Qstring,我想编写一个模板函数,它可以处理QString和std::string,以减少复制的代码。不幸的是,QString没有实现substr成员函数QString::mid(int,int)似乎是Qt类似物。处理这种差异的最佳方法是什么?下面是我的函数,它应该作用于std::string-like对象: 模板功能: template <typename StringType> void do_something(StringType s, StringType::size_type sta

我想编写一个模板函数,它可以处理
QString
std::string
,以减少复制的代码。不幸的是,
QString
没有实现
substr
成员函数
QString::mid(int,int)
似乎是Qt类似物。处理这种差异的最佳方法是什么?下面是我的函数,它应该作用于std::string-like对象:

模板功能:

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;
}
模板
void do_something(StringType s,StringType::size_type start,StringType::size_type length){
//如果StringType==QString,则未定义
StringType sub_s=s.substr(起点,长度);
//对子字符串执行某些操作,例如:

std::coutstd::string
QString
都有
data()
size()
成员,因此您可以为统一的字符串操作构造一个:

#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;
}
#包括
#包括
模板
void do_something(StringType const&s,typename StringType::size_type start,typename StringType::size_type length)
{   
标准::基本字符串视图sv(s.data(),s.size());
自动分段=sv.substr(起点、长度);
//对子字符串执行某些操作,例如:

std::coutstd::string
QString
都有
data()
size()
成员,因此您可以为统一的字符串操作构造一个:

#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;
}
#包括
#包括
模板
void do_something(StringType const&s,typename StringType::size_type start,typename StringType::size_type length)
{   
标准::基本字符串视图sv(s.data(),s.size());
自动分段=sv.substr(起点、长度);
//对子字符串执行某些操作,例如:

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

我认为最简单的方法是使用
QString
tostString()
函数。您可以使用默认的
std::string
版本编写所有功能,然后通过将
QString
的内容转换为
std::string
来专门化只调用
std::string
版本的
QString重载版本。我将使用一个简单的
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;
}

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

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

我认为最简单的方法是使用
QString
tostString()
函数。您可以使用默认的
std::string
版本编写所有功能,然后通过将
QString
的内容转换为
std::string
来专门化只调用
std::string
版本的
QString重载版本。我将使用一个简单的
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;
}

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

Traits/Policy或简单重载似乎可以处理不同的部分。
QString
具有
begin()
end()
成员,因此任何成员都应该同等工作。用户zett42提供了一个优秀有效的解决方案,但我的回答提供了另一种方法,使用
QString
tostString()
成员函数。我想我应该为您提供另一个工作解决方案,因为它会增加可用的工具集。Traits/Policy或简单重载似乎可以处理不同的部分。
QString
具有
begin()
end()
成员,因此任何成员都应该平等工作。用户zett42提供了一个优秀而有效的解决方案,但是我的回答提供了一种使用
QString
tostString()的替代方法
member函数。我想我应该为您提供另一个工作解决方案,因为它会增加可用的工具集。您可以使用重载而不是专门化。您可以创建(不必要的)copyThat可通过移动语义轻松修复:我可以更新答案以反映它。对于您的更改,最好对printString使用const引用,并删除所有std::move。编辑以反映我的上一句话。我的主要意思是“转换”从
QString
string
进行分配,这并不总是需要/接受的。在某些情况下可能会很好,但如果字符串很大,则可能会出现问题。您可能会使用重载而不是专门化。您创建了(不必要的)copy可以很容易地用move语义修复:我可以更新答案以反映它。对于您的更改,最好对printString使用const引用,并删除所有std::move。编辑以反映我的上一句话。我主要的意思是从
QString
string
的“转换”不允许