Как использовать аргумент шаблона класса для изменения вызовов аргументов и сигнатур функций?

Я пытаюсь найти способ разработать шаблон класса, чтобы значение int передавалось, и несколько сигнатур функций, а также списки аргументов зависят от этого значения.

В частности, учитывая 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));
    };
};

Я хотел бы иметь возможность выражать как частный вызов typedef, подпись myFunction, так и список аргументов, передаваемых внешним функциям someFunction и someOtherFunction, которые я не могу редактировать/переписывать. Есть ли способ добиться этого, используя стандарт С++ 11?


person joaocandre    schedule 24.05.2020    source источник
comment
почему бы не использовать пакет параметров?   -  person yaodav    schedule 24.05.2020
comment
Или, может быть, std::array‹int, N›?   -  person kjpus    schedule 24.05.2020
comment
@yaodav Кажется, это может помочь, я посмотрю на это; @kjpus Я думал об этом, но someFunction и someOtherFunction принимают каждый аргумент по отдельности и, поскольку они не являются моим кодом, не могут изменить свою подпись.   -  person joaocandre    schedule 24.05.2020
comment
Я думаю, что мой предыдущий ответ отлично отвечает вам, если вы что-то не поняли.   -  person asmmo    schedule 25.05.2020
comment
Я все еще пытаюсь понять, как любой из этих ответов проверяет все требования. На этот раз никто из них не задумывается, как передать порядок аргументов в boost::bind, что, честно говоря, является моей главной проблемой. С другой стороны, я признаю, что у меня нет большого опыта с такого рода статическим программированием.   -  person joaocandre    schedule 25.05.2020


Ответы (2)


Вы можете использовать трюк, как в этом сообщении (Создать std::tuple того же типа во время компиляции, учитывая его длину с помощью аргумента шаблона), чтобы создать кортеж из N элементов.

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);
};
person sturcotte06    schedule 24.05.2020
comment
Аккуратное решение (я приберегу этот трюк с кортежами на потом), но для этого требуется, чтобы аргументы функций были кортежами, верно? Я не могу изменить прототипы функции. - person joaocandre; 24.05.2020
comment
Не совсем, вы могли бы сделать это с пакетом параметров + кортежем для доступа к индексам. Или вы можете использовать массив. вы можете сделать что-то вроде template <typename... Ts> void int_function(Ts&&... elements) { int_function(std::make_tuple(std::forward<Ts>(elements)...); }. Однако это решение требует двух методов для каждой реализации. - person sturcotte06; 24.05.2020

Вы можете использовать std::index_sequence (С++ 14, но реализацию на С++ 11 можно найти на 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>>;
person Jarod42    schedule 24.05.2020