简体   繁体   中英

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 .

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.

Second try:

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

This time the output came as expected:

"default_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.

"default_E_"

When testing for timing, I've found out that the append option is faster that the += .

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.

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" :

#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 << ):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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