Use std::tuple for template parameter list instead of list of types

后端 未结 2 1944
梦谈多话
梦谈多话 2021-01-13 13:07

I\'m trying to make a call to a templated function like this :

typedef std::tuple Instrument         


        
2条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-13 13:46

    Here is what I came up with:

    #include 
    
    struct Cache;
    
    /* typename = std::tuple<...> */
    template struct cache_getter;
    /* typename = parameters from std::tuple<...> */
    template struct tuple_walker;
    
    template struct cache_getter > {
        static std::tuple get(Cache & c);
    };
    
    struct Cache {
    protected:
        template friend struct tuple_walker;
    private:
        /* here T is a type from within a std::tuple<...> */
        template std::tuple get_ex() {
            return std::tuple();
        }
    public:
        /* here T is actually a std::tuple<...> */
        template T get() {
            return cache_getter<0, T>::get(*this);
        }
    };
    
    /* since std::tuple_cat only accepts 2 std::tuples per call but we don't have control over the number of types in the passed in std::tuple, we'll need to chain our calls */
    template struct my_tuple_cat;
    template struct my_tuple_cat {
        static auto cat(H h, T... t) -> decltype(std::tuple_cat(h, my_tuple_cat::cat(t...)))
        { return std::tuple_cat(h, my_tuple_cat::cat(t...)); }
    };
    template struct my_tuple_cat {
        static T cat(T t) { return t; }
    };
    
    /* this one is used to call Cache.get_ex() with incrementing values for I */
    template struct tuple_walker {
        static std::tuple get(Cache & c) {
            return my_tuple_cat, std::tuple>::cat(c.get_ex(), tuple_walker::get(c));
        }
    };
    template struct tuple_walker {
        static std::tuple get(Cache & c) {
            return c.get_ex();
        }
    };
    /* this one will forward the types in std::tuple<...> to tuple_walker to get each tuple separately */
    template std::tuple cache_getter >::get(Cache & c) {
        return tuple_walker::get(c);
    }
    
    int main(int argc, char ** argv) {
        Cache cache;
        typedef std::tuple InstrumentTuple;
        InstrumentTuple tuple = cache.get();
        return 0;
    }
    

    I hope this is worth something. I haven't done much in C++11 yet, so maybe this isn't an optimal solution.

    Proof that it compiles can be found here

提交回复
热议问题