How to use class template argument to change argument calls and function signatures?

不羁的心 提交于 2020-06-01 07:40:28

问题


I am trying to find way to design a class template so that an int value is passed, and several function signatures as well as argument lists are dependent on this value.

Particularly, considering MyClass:

template <int N>
class MyClass {
    typedef SomeType<int, int, int, /* ... N times*/ > MyDepType;
    myFunction(std::string arg0, std::string  arg1, /* ...*/ std::string  argN) { /* do stuff */};
 public:
    MyClass() {
        someFunction(float arg0, float arg1, /* ...*/ float argN);   // <
        someOtherFunction(boost::bind(&MyClass::myFunction, this, _1, _2, /*...*/ _N));
    };
};

I'd like to be able to express both the private typedef call, the signature of myFunction and the argument list passed to external functions someFunction and someOtherFunction, which I can't edit/rewrite. Is there a way to achieve this, using the C++11 standard?


回答1:


You could use a trick like in this post (Produce std::tuple of same type in compile time given its length by a template argument) to produce a tuple of N elements.

template <int N, typename T> 
struct tuple_n_impl {
    template <typename... Ts> 
    using type = typename tuple_n_impl<N - 1, T>::template type<T, Ts...>;
};

template <typename T> 
struct tuple_n_impl<0, T> {
    template <typename... Ts> 
    using type = std::tuple<Ts...>;
};

template <int N, typename T>
using tuple_n = typename tuple_n_impl<N, T>::template type<>;

template <int N>
class MyClass {
    void int_function(tuple_n<N, int>&& ints);
    void float_function(tuple_n<N, float>&& floats);

    template <typename T> 
    void any_function(tuple_n<N, T>&& elements);
};



回答2:


You might use std::index_sequence (C++14, but implementation in C++11 can be found on SO):

template <std::size_t, typename T>
using always_t = T;

template <std::size_t ... Is>
class MyClassImpl {
    using MyDepType = SomeType<always_t<Is, int>...>;
    void myFunction(always_t<Is, std::string>... args) { /* do stuff */}
 public:
    MyClass() {
        void someFunction(always_t<Is, std::float>... args);
        someOtherFunction([this](always_t<Is, const std::string&>... args) {
            return myFunction(args...);
        });

        // 
        std::array<std::string, sizeof...(Is)> strings = {std::to_string(Is)...};
        myFunction(strings[Is]...);
    };
};

template <std::size_t N>
using MyClass = MyClassImpl<std::make_index_sequence<N>>;


来源:https://stackoverflow.com/questions/61990155/how-to-use-class-template-argument-to-change-argument-calls-and-function-signatu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!