Is it possible to invoke a method with all possible K-combinations (with repetition) of arguments passed in a tuple?

后端 未结 1 996
南旧
南旧 2021-01-20 17:12

The desired behaviour can be illustrated as follows:

void foo(int x, int y) {
    std::cout << x << \" \" << y << std::endl;
}

int m         


        
1条回答
  •  迷失自我
    2021-01-20 17:55

    The c++14 version could look as follows:

    #include 
    #include 
    #include 
    #include 
    
    
    template 
    int all_combinations_impl(Foo foo, Tuple t, std::index_sequence , std::integral_constant, std::index_sequence) {
       foo(std::get(t)...);
       std::cout << std::endl;
       return 0;
    }
    
    template 
    int all_combinations_impl(Foo foo, Tuple t, std::index_sequence, std::integral_constant, std::index_sequence is) {
       std::initializer_list all = {all_combinations_impl(foo, t, std::index_sequence{}, std::integral_constant{}, is)...};
       (void)all;
    }
    
    template 
    void all_combinations(Foo foo, Tuple t) {
       all_combinations_impl(foo, t, std::index_sequence<>{}, std::integral_constant{}, std::make_index_sequence::value>{});
    }
    
    int main() {
       all_combinations<2>([](auto... args) { std::forward_as_tuple((std::cout << args)...); }, std::make_tuple("1 ", "2 ", "3 "));
    }
    

    Unfortunately c++11 does not come with std::integer_sequence, so we need to do additional implementation:

    #include 
    #include 
    #include 
    #include 
    
    template 
    struct integer_sequence { };
    
    template , class = integer_sequence, class = void>
    struct make_integer_sequence_impl;
    
    template 
    struct make_integer_sequence_impl, std::integral_constant, integer_sequence, integer_sequence, typename std::enable_if<(ICV1 > 0)>::type>: make_integer_sequence_impl, std::integral_constant, integer_sequence, integer_sequence> { };
    
    template 
    struct make_integer_sequence_impl, std::integral_constant, integer_sequence, integer_sequence, void>: make_integer_sequence_impl, std::integral_constant, integer_sequence, integer_sequence> { };
    
    template 
    struct make_integer_sequence_impl, std::integral_constant, Res, Pow, void> {
       using type = Res;
    };
    
    template 
    using make_integer_sequence = typename make_integer_sequence_impl, std::integral_constant>::type;
    
    template 
    using make_index_sequence = make_integer_sequence;
    
    template 
    using index_sequence = integer_sequence;
    
    template 
    int all_combinations_impl(Foo foo, Tuple t, index_sequence , std::integral_constant, index_sequence) {
       foo(std::get(t)...);
       std::cout << std::endl;
       return 0;
    }
    
    template 
    int all_combinations_impl(Foo foo, Tuple t, index_sequence, std::integral_constant, index_sequence is) {
       std::initializer_list all = {all_combinations_impl(foo, t, index_sequence{}, std::integral_constant{}, is)...};
       (void)all;
    }
    
    template 
    void all_combinations(Foo foo, Tuple t) {
       all_combinations_impl(foo, t, index_sequence<>{}, std::integral_constant{}, make_index_sequence::value>{});
    }
    
    struct s {
       template 
       void operator()(Args... args) const {
          std::forward_as_tuple((std::cout << args)...);
       }
    };
    
    int main() {
       all_combinations<3>(s{}, std::make_tuple("1 ", "2 ", "3 "));
    }
    

    0 讨论(0)
提交回复
热议问题