Есть ли способ реализовать аналог Python 'separator'.join() в С++?

Все, что я нашел, это boost::algorithm::string::join. Тем не менее, кажется, что overkill использует Boost только для соединения. Так, может быть, есть некоторые проверенные временем рецепты?

UPDATE:
К сожалению, заголовок вопроса был плохим. Я ищу метод для объединения строк с разделителем, а не только для конкатенации один за другим.

Ответ 1

Так как вы ищете рецепт, используйте его и используйте Boost. После того, как вы преодолеете всю родословность, это не слишком сложно:

  • Выделите место для хранения результата.
  • Добавить первый элемент последовательности в результат.
  • Пока есть дополнительные элементы, добавьте разделитель и следующий элемент в результат.
  • Верните результат.

Здесь версия, которая работает на двух итераторах (в отличие от версии Boost, которая работает в диапазоне.

template <typename Iter>
std::string join(Iter begin, Iter end, std::string const& separator)
{
  std::ostringstream result;
  if (begin != end)
    result << *begin++;
  while (begin != end)
    result << separator << *begin++;
  return result.str();
}

Ответ 2

Если вы действительно хотите ''.join(), вы можете использовать std::copy с std::ostream_iterator до std::stringstream.

#include <algorithm> // for std::copy
#include <iterator>  // for std::ostream_iterator

std::vector<int> values(); // initialize these
std::stringstream buffer;
std::copy(values.begin(), values.end(), std::ostream_iterator<int>(buffer));

Это введет все значения в buffer. Вы также можете указать пользовательский разделитель для std::ostream_iterator, но это будет добавлено в конце (это существенная разница с join). Если вам не нужен разделитель, это сделает именно то, что вы хотите.

Ответ 3

Строки С++ реализованы эффективно.

std::string s = s1 + s2 + s3;

Это может быть быстрее:

std::string str;
str.reserve(total_size_to_concat);

for (std::size_t i = 0; i < s.length(); i++)
{
  str.append(s[i], s[i].length());
}

Но это в основном то, что ваш компилятор делает с operator+ и минимум оптимизации, за исключением того, что он угадывает размер резерва.
Не стесняйтесь. Посмотрите реализацию строк.:)

Ответ 4

Если вы используете Qt в своем проекте, вы можете напрямую использовать функцию join QString (QString Reference), и она работает как ожидалось из python. Некоторые примеры:

QStringList strList;
qDebug() << strList.join(" and ");

Результат: ""

strList << "id = 1";
qDebug() << strList.join(" and ");

Результат: "id = 1"

strList << "name = me";
qDebug() << strList.join(" and ");

Результат: "id = 1 and name = me"

Ответ 5

Вот еще одна версия, которую я считаю более удобной в использовании:

std::string join(std::initializer_list<std::string> initList, const std::string& separator = "\\")
{
    std::string s;
    for(const auto& i : initList)
    {
        if(s.empty())
        {
            s = i;
        }
        else
        {
            s += separator + i;
        }
    }

    return s;
}

Затем вы можете называть это следующим образом:

join({"C:", "Program Files", "..."});