我想在所有的第一个和最后一个参数中分割一个参数包,但是C++要求参数包是函数声明中的最后一个,所以这是无效的代码。
template<typename... Ts, typename Last>
void func( Ts... args, Last last ) {
cout << "{ ";
( (cout << args << ", "), ... ) << last << " }\n";
}现在,我可以用一些不太好的代码来达到这个目的:
template<typename T0, typename T1, typename Last>
pair< tuple<T0, T1>, tuple<Last> > slice( T0 t0, T1 t1, Last last ) {
return { make_tuple( t0, t1 ), make_tuple( last ) };
}
template<typename T0, typename T1, typename T2, typename Last>
pair< tuple<T0, T1, T2>, tuple<Last> > slice( T0 t0, T1 t1, T2 t2, Last last ) {
return { make_tuple( t0, t1, t2 ), make_tuple( last ) };
}
template<typename... Ts>
void func( Ts... ts ) {
auto f = [](auto last, auto... args) {
cout << "{ ";
( (cout << args << ", "), ... ) << last << " }\n";
};
apply( f, tuple_cat( slice(ts...).second, slice(ts...).first ) );
}
int main() {
func( "Hello", 4, 5 );
func( "Hello", 4, 5.4, "Mars"s );
}但是如何正确地制作slice()呢?
发布于 2022-08-11 21:04:34
您可以将其转换为元组来处理它。
void f(){}; // empty pack
template<typename ...Ts>
void f(Ts&&... ts) {
auto tuple = std::forward_as_tuple(std::forward<Ts>(ts)...);
constexpr auto size = sizeof...(Ts);
auto&& last = std::get<size-1>(tuple);
[&]<std::size_t ...I>(std::index_sequence<I...>){
((std::cout << std::get<I>(tuple) << " , "), ...);
}(std::make_index_sequence<size-1>());
std::cout << last << '\n';
}但在这种情况下,更改顺序更简单(如@ HolyBlackCat所说)
template<typename T, typename ...Ts>
void f(T&& t, Ts&&... ts) {
std::cout << t;
((std::cout << " , " << ts),...);
std::cout << '\n';
}发布于 2022-08-12 08:34:42
这是一个切片函数。
template<typename ...Ts>
auto slice_last(Ts&&... args){
auto tuple = std::forward_as_tuple(std::forward<Ts>(args)...);
constexpr auto size = sizeof...(Ts);
auto without_last =
[&]<std::size_t ...I>(std::index_sequence<I...>){
return std::forward_as_tuple(std::get<I>(std::move(tuple))...);
}(std::make_index_sequence<size-1>());
using last_type = std::tuple_element_t<size-1,decltype(tuple)>;
return std::pair<decltype(without_last),last_type>(
std::move(without_last),
std::get<size-1>(std::move(tuple))
);
}
// use
template<typename... Ts>
void f(Ts&&... ts) {
auto [pack,last] = slice_last(std::forward<Ts>(ts)...);
cout << "{ ";
std::apply(
[](auto&&...ts){( (std::cout<<ts<<" ,"), ... );}
,pack
);
std::cout << last << " }\n";
}发布于 2022-08-11 19:28:43
下面是args_filter_apply()的一个相对简单的实现,它使用运行时过滤的参数包调用lambda。它还不是最优的,但您可能会有这样的想法:
#include <iostream>
template<typename Filter, typename Funct>
auto args_filter_apply(Filter filter, Funct funct)
{
return funct();
}
template<typename Filter, typename Funct, typename Arg, typename... Args>
auto args_filter_apply(Filter&& filter, Funct&& funct, Arg& arg, Args&... args)
{
if (filter(arg)) {
return args_filter_apply(std::forward<Filter>(filter), [&](auto... args1) {
return std::forward<Funct>(funct)(arg, args1...);
}, args...);
}
return args_filter_apply(std::forward<Filter>(filter), std::forward<Funct>(funct), args...);
}
template<typename... Ts>
void func(Ts... args) {
std::cout << "{ ";
int i = 0;
args_filter_apply([&](auto arg) {
return ++i != sizeof...(args);
}, [](auto... myArgs) {
( (std::cout << myArgs << ", "), ... );
}, args...);
i = 0;
args_filter_apply([&](auto arg) {
return ++i == sizeof...(args);
}, [](auto... last) {
( (std::cout << last), ...);
std::cout << " }\n";
}, args...);
}
int main()
{
func("Hello", 4, 5);
func("Hello", 4, 5.4, "Mars");
}https://stackoverflow.com/questions/73325677
复制相似问题