通过改变推导出的模板值来自组成函数

Self-composing a function with changing deduced template value

本文关键字:函数 改变      更新时间:2023-10-16

如何执行self_composeN(func)(x)如果func有一个导出的模板值,需要每次更改?举个例子吧?这里我写了rotate_tuple它将给定元组的所有元素向左旋转N,我想多次应用它(我知道我可以用N乘以任何东西来实现这一点,但我想知道它的通用解,因为会有其他这样的函数没有这样的捷径)。下面是rotate_tuple的代码,它已经经过了彻底的测试(它也提取了结果类型)。你不需要担心细节,我不认为,除了struct rotate_tuple本身,它很短。

#include <tuple>
#include <string>
#include <functional>
template <int NUM_LEFT, int SHIFT>
class rotate_tuple_helper {
    private:
        static constexpr int positiveModulo (int i, int n) {return (i % n + n) % n;}
        template <typename TUPLE>
        static constexpr int shift() {return positiveModulo (SHIFT, std::tuple_size<TUPLE>::value);}
    public:
        template <typename TUPLE>
        auto operator() (const TUPLE& t) const -> decltype (std::tuple_cat (std::make_tuple (std::get<shift<TUPLE>()>(t)), rotate_tuple_helper<NUM_LEFT-1, SHIFT+1>()(t))) {    
            return std::tuple_cat (std::make_tuple (std::get<shift<TUPLE>()>(t)), rotate_tuple_helper<NUM_LEFT-1, SHIFT+1>()(t));
        }
};
template <int SHIFT>
class rotate_tuple_helper<0, SHIFT> {
    public:
        template <typename TUPLE>
        std::tuple<> operator() (const TUPLE& t) const {return std::tuple<>();} 
};
template <typename TUPLE, int SHIFT>
struct rotate_tuple_type {
    using type = decltype (rotate_tuple_helper<std::tuple_size<TUPLE>::value, SHIFT>()(std::declval<TUPLE>()));
};
template <int SHIFT>
struct rotate_tuple {
    template <typename TUPLE>
    typename rotate_tuple_type<TUPLE, SHIFT>::type operator() (const TUPLE& t) const {
        return rotate_tuple_helper<std::tuple_size<TUPLE>::value, SHIFT>()(t);
    }
};
int main() {
    using tuple_type = std::tuple<int, std::string, double, char, std::string, int, double, char>;
    const tuple_type t (8, "house", 3.14, 'b', "apple", 6, 1.5, '!');
    using rotate_tuple_type = rotate_tuple_type<tuple_type, 3>::type;
    const rotate_tuple_type result = rotate_tuple<3>()(t); //(b, apple, 6, 1.5, !, 8, house, 3.14)
}

无论如何,我想做一些事情来达到self_compose<10> (rotate_tuple<3> ()) (t);(不用直接把3改成30)。有人能帮忙吗?c++/c++ 11中函数组合的例子在这里不太适用,因为它实际上不是被重用的同一个函数。rotate_tuple<3>()的导出模板值T不断变化(因为生成的元组类型不断变化),因此我们实际上没有自我组合。我想self_compose不是个好名字,应该是self_repeat。无论如何,关于如何编写self_repeat(不特定于rotate_tuple的通用解决方案)的任何想法?

您可以使用以下命令:

template <std::size_t N, typename Functor> struct self_composeN
{
    template <typename T>
    constexpr auto operator () (T t) const -> Return((self_composeN<N - 1, Functor>()(Functor()(t))))
};
template <typename Functor> struct self_composeN<0u, Functor>
{
    template <typename T>
    constexpr T operator () (T t) const { return t; }
};

生活例子。