Search code examples
c++concatenationg++std-rangesc++23

concatenate ranges using join


trying to join (concat) ranges using g++14. Is there a way to do this ?

#include <ranges>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;

int main(){

    const vector<string> v = {"1","2","3"};

    const auto vv = {
        "{",
        v | views::join_with(','),
        "}"
    };

    const string buf = vv | views::join | ranges::to<string>();

}

Error:

prog.cc: In function 'int main()':
prog.cc:15:5: error: unable to deduce 'const std::initializer_list<auto>' from '{"{", std::ranges::views::__adaptor::operator|<_Partial<std::ranges::views::_JoinWith, char>, const std::vector<std::__cxx11::basic_string<char> >&>(v, ((const std::ranges::views::__adaptor::_RangeAdaptor<std::ranges::views::_JoinWith>*)(& std::ranges::views::join_with))->std::ranges::views::__adaptor::_RangeAdaptor<std::ranges::views::_JoinWith>::operator()<char>(',')), "}"}'
   15 |     };
      |     ^
prog.cc:15:5: note:   deduced conflicting types for parameter 'auto' ('const char*' and 'std::ranges::join_with_view<std::ranges::ref_view<const std::vector<std::__cxx11::basic_string<char> > >, std::ranges::single_view<char> >')

Solution

  • If you know how to wrap the joined string you can use std::format

    std::format("{{{}}}", vv);
    

    note that std::format uses a format string with {} to place arguments which follow the format string, thus the inner most {} will be replaced by vv. To escape a brace, double braces are used, hence {{ and }} left and right of {}. godbolt link of the full example.

    To get rid of the verbose std::sting("..."), consider using using namespace std::literals; which allows for "..."s instead.