The problem I got is I have a function that takes a variadic argument. I want to use this for fmt
printing . The way I am trying to achieve this is by joining them.
I have my join function:
template <typename RANGE, typename Projection = std::identity>
inline auto join(const RANGE& range, std::string_view sep, Projection&& proj = std::identity{}) {
auto joined = range
| std::views::transform([&proj](const auto& element) { return std::invoke(proj, element); })
| std::views::join_with(sep);
return std::ranges::to<std::string>(joined);
}
for now ignore std::invoke
as it is simply deducing to the identity i.e. std::format("{}");
If I supply a vector it works fine, however, if I got a variadic function like:
template<Args..>
foo(Args... args) {
std::string goo = std::format(
"Show me the keys: {}",
join(args..., ",")
);
}
It does not work. I also tried with std::forward_as_tuple
to cast my args
to a std::tuple
, however, that did not help since operand |
is not supported by std::tuple
.
I have an example here showing the case with a std::vector
and std::tuple
(in conjunction with variadic arguments)
The whole example is pasted below:
#include <iostream>
#include <string>
#include <vector>
#include <ranges>
#include <format>
#include <functional>
template <typename RANGE, typename Projection = std::identity>
inline auto join(const RANGE& range, std::string_view sep, Projection&& proj = std::identity{}) {
auto joined = range
| std::views::transform([&proj](const auto& element) { return std::invoke(proj, element); })
| std::views::join_with(sep);
return std::ranges::to<std::string>(joined);
}
template<typename... KEYS>
auto get(KEYS... keys) {
return std::forward_as_tuple(std::forward<KEYS>(keys)...);
}
int main() {
auto tuple_range = get("bla", "blas", "blaaaass");
auto vv = std::vector<std::string>{"bla", "blas", "blaass"};
std::string goo = std::format(
"Show me the keys: {}",
join(vv, ",")
);
std::cout << goo << std::endl;
return 0;
}
Tuples aren't ranges. A range, in C++ terms, requires that all elements of the range are of the same type. Tuples aren't like that, so they cannot be manipulated by any range mechanisms.