A C++ implementation of a join() function similar to Python and JavaScript, demonstrating how to concatenate a vector of strings with a separator.

The Question

Many high-level languages like Python and JavaScript provide a convenient join() method for arrays/lists:

# Python
" ".join(["foo", "bar"])  # Returns "foo bar"
// JavaScript
["foo", "bar"].join(" ")  // Returns "foo bar"

But what about C++? Can we implement something similar?

The Solution

Here’s a template-based implementation using std::accumulate:

template <typename Iter>
string join(Iter begin, Iter end, std::string const& sep) {
    static_assert(is_same_v<typename Iter::value_type, std::string>);
    if(begin == end) { return ""; }
    if(std::next(begin) == end) { return *begin; }
    return std::accumulate(std::next(begin), end, *begin
                          ,[&sep](std::string const& a, std::string const& b) {
                            return a + sep + b;
                          });
}

How It Works

  1. Template parameter: Accepts any iterator type
  2. Static assertion: Ensures the iterator points to std::string values
  3. Edge case handling:
    • Empty range: returns empty string
    • Single element: returns that element without separator
  4. Accumulation: Uses std::accumulate with a lambda to concatenate strings
  5. Separator injection: The lambda adds the separator between each pair of strings

Usage Example

#include <vector>
#include <string>
#include <iostream>

int main() {
    std::vector<std::string> words = {"foo", "bar", "baz"};
    std::string result = join(words.begin(), words.end(), " ");
    std::cout << result << std::endl;  // Output: "foo bar baz"
    return 0;
}

Key Features

  • Iterator-based: Works with any container that provides iterators
  • Type safety: Static assertion ensures string compatibility
  • Edge case handling: Properly handles empty and single-element containers
  • Efficient: Uses std::accumulate for optimal performance
  • Generic: Template design allows for different iterator types

This implementation provides C++ with the same convenient string joining functionality found in higher-level languages, while maintaining type safety and performance.