Apply the first valid function of a set of N functions

前端 未结 5 2045
南旧
南旧 2020-12-10 06:52

This previous answer shows how to apply function based on the validity of a call: here. However, it applies to two functions. I was wondering if the concept could be general

5条回答
  •  被撕碎了的回忆
    2020-12-10 07:27

    Here's another fun one for kicks, abusing overload resolution. We're going to transform each function into another function that takes a rank argument, combine all of our functions together, and then just invoke them. The selection will just fall out naturally from the overload set.

    Our ranker is just this ladder of types:

    template  struct rank : rank { };
    template <> struct rank<0> { };
    

    We need a function transformer:

    template 
    auto prepend_arg(F&& f) {
        return [f=std::forward(f)](T, auto&&... args)
            -> decltype(std::forward(f)(std::forward(args)...))
        {
            return std::forward(f)(std::forward(args)...);
        };
    }
    

    And then:

    template 
    decltype(auto) apply_impl(std::index_sequence,
                              std::index_sequence,
                              X&&... x)
    {
        auto all = std::forward_as_tuple(std::forward(x)...);
    
        return overload(
            // all of our function cases
            prepend_arg>(std::get(all))...,
            // base case: do nothing
            [](rank<0>, auto&&...) {}
        )(rank{}, std::get(all)...);
    //               ^^^^^^^^^^^^^^^^^^^^^^^^
    //               pass in all the arguments    
    }
    
    template 
    decltype(auto) apply_on_validity(X&&... x) {
        return apply_impl(
            std::make_index_sequence{},
            std::make_index_sequence{},
            std::forward(x)...);
    }
    

    I leave overload() as an exercise.

提交回复
热议问题