首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >切片参数包参数

切片参数包参数
EN

Stack Overflow用户
提问于 2022-08-11 18:59:19
回答 5查看 99关注 0票数 0

我想在所有的第一个和最后一个参数中分割一个参数包,但是C++要求参数包是函数声明中的最后一个,所以这是无效的代码。

代码语言:javascript
复制
template<typename... Ts, typename Last>
void func( Ts... args, Last last ) {
    cout << "{ ";
    ( (cout << args << ", "), ... ) << last << " }\n";
}

现在,我可以用一些不太好的代码来达到这个目的:

代码语言:javascript
复制
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()呢?

https://godbolt.org/z/qbbP1YM9T

EN

回答 5

Stack Overflow用户

发布于 2022-08-11 21:04:34

您可以将其转换为元组来处理它。

代码语言:javascript
复制
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所说)

代码语言:javascript
复制
template<typename T, typename ...Ts>
void f(T&& t, Ts&&... ts) {
    std::cout << t;
    ((std::cout << " , " << ts),...);
    std::cout << '\n';
}
票数 1
EN

Stack Overflow用户

发布于 2022-08-12 08:34:42

这是一个切片函数。

代码语言:javascript
复制
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";
}
票数 1
EN

Stack Overflow用户

发布于 2022-08-11 19:28:43

下面是args_filter_apply()的一个相对简单的实现,它使用运行时过滤的参数包调用lambda。它还不是最优的,但您可能会有这样的想法:

代码语言:javascript
复制
#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");
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73325677

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档