简体   繁体   English

在 C++ 中连接多个字符串的最有效方法

[英]Most efficient way to concatenate multiple strings in C++

I want to find the most efficient way to concatenate multiple strings of type std::string .我想找到连接多个std::string类型字符串的最有效方法。

One of the issues is that I also have a char within it, and another issue is that I need it to be as fast as possible.一个问题是我里面也有一个字符,另一个问题是我需要它尽可能快。 Let's say I have the following variables defined:假设我定义了以下变量:

std::string defaultName = "default"; 
std::string paramFullName = "Elasticity";

First try:第一次尝试:

std::string paramName = defaultName + "_" + paramFullName[0] + "_";

This code does not compile with Intel C++14 compiler.此代码无法使用英特尔 C++14 编译器进行编译。

Second try:第二次尝试:

std:string paramName;
paramName += defaultName + "_";
paramName += paramFullName[0];
paramName += "_";

This time the output came as expected:这次输出如预期的那样:

"default_E_" “默认_E_”

I still wanted to test another way:我仍然想测试另一种方式:

Third try:第三次尝试:

std:string paramName;
paramName.append(defaultName + "_");
paramName.append(1, paramFullName[0]);
paramName.append("_");

Output was OK again, because of the separation of the char from the string s.输出再次正常,因为charstring s 分离。

"default_E_" “默认_E_”

When testing for timing, I've found out that the append option is faster that the += .在测试时间时,我发现append选项比+=更快。

I want to know if there is a better, more efficient way,我想知道是否有更好,更有效的方法,
and also could I minimize the number of lines so it wouldn't look so ugly?我也可以尽量减少行数,使它看起来不那么难看吗?

The fastest way is most likely going to involve allocating a destination string once, which means you will need to know the size of all your input strings.最快的方法很可能涉及分配一次目标字符串,这意味着您需要知道所有输入字符串的大小。 Luckily std::string , string literals and individual characters have a O(1) size, so only c style strings need to be looped twice.幸运的是std::string ,字符串文字和单个字符的大小为 O(1),因此只有 c 样式的字符串需要循环两次。

namespace string_builder
{
    std::size_t length(char str)
    {
        return 1;
    };
    
    void append(std::string & dest, char str)
    {
        dest.push_back(str);
    }
    
    std::size_t length(const char * str)
    {
        return std::strlen(str);
    };
    
    void append(std::string & dest, const char * str)
    {
        dest.append(str);
    }
    
    template<std::size_t N>
    std::size_t length(const char (&str)[N])
    {
        return N;
    }
    
    template<std::size_t N>
    void append(std::string & dest, const char (&str)[N])
    {
        dest.append(str, N);
    }
    
    std::size_t length(const std::string & str)
    {
        return str.size();
    }
    
    void append(std::string & dest, const std::string & str)
    {
        dest.append(str);
    }
}

template<typename... Ts>
std::string concat(const Ts &... ts)
{
    std::string result;
    result.reserve((string_builder::length(ts) + ...));
    (string_builder::append(result, ts), ...);
    return result;
}

See it on coliru在大肠杆菌上看到它

Use the "built-in" C++ "stringbuilder" :使用“内置”C++“stringbuilder”:

#include <iostream> // for std::cout
#include <sstream>  // for std::ostringstream
#include <string>   // for std::string

int main()
{
    std::ostringstream oss;
    std::string s("Two");
    oss << "One" << ' ' << s << ' ' << "Three";
    std::string result(oss.str()); // concat result
    std::cout << result; // Console Output: One Two Three
}

OR (more concise, not using result variable)或(更简洁,不使用结果变量)

std::cout << oss.str();

Using ostringstream object you can also concatenate any type of variables, provided that all of them are "streamable" (standard stream or the type itself know how to serialize what you are sending after operator << ):使用 ostringstream 对象,您还可以连接任何类型的变量,前提是它们都是“可流式的”(标准流或类型本身知道如何序列化您在 operator << 之后发送的内容):

std::ostringstream oss;
int one = 1;
std::string s("Two");
oss << one << ' ' << s << ' ' << 3;
std::string result(oss.str()); // concat result
std::cout << result; // Output: 1 Two 3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM