Вопрос по c++ – Любое решение, чтобы распаковать вектор для аргументов функции в C ++?

4

На самом деле я думаю о чем-то похожем на «*»; оператор в питоне так:

args = [1,2,4]
f(*args)

Есть ли подобное решение в C ++?

Я могу придумать следующее:

template <size_t num_args, typename FuncType>
struct unpack_caller;

template <typename FuncType>
struct unpack_caller<3>
{
    void operator () (FuncType &f, std::vector<int> &args){
        f(args[0], args[1], args[3])
    }
};

Выше я предполагаю толькоint тип аргумента.

Проблема в том, что я чувствую, что написать все специализации unpack_caller для разных значенийnum_args.

Любое хорошее решение для этого? Благодарю.

@templatetypedef Хотя размер вектора является переменной времени выполнения, число аргументов функции является константой времени компиляции. Вот почему это возможно. Мы можем схватить егоboost::function_traits<f>::arity Danqi Wang
templatetypedef: это, безусловно, возможно. Смотрите решение, данное @R. Мартиньо Фернандес. Nawaz
@ DanqiWang - если вы разрешите использование функций с переменными значениями (используя шаблоны с переменными значениями или переменные), решение, перечисленное ниже, не будет работать. Это было беспокойство, которое я изначально озвучивал. templatetypedef
Я подозреваю, что ответ - нет. Число аргументов функций является конструкцией времени компиляции, в то время как количество элементов в векторе является конструкцией времени выполнения. Я не могу доказать, что это невозможно, но я сильно подозреваю, что это так. templatetypedef
@templatetypedef Я согласен. Я не принял это во внимание. Хорошая точка зрения. Danqi Wang

Ваш Ответ

1   ответ
5

пакет показателей:

template <size_t num_args>
struct unpack_caller
{
private:
    template <typename FuncType, size_t... I>
    void call(FuncType &f, std::vector<int> &args, indices<I...>){
        f(args[I]...);
    }

public:
    template <typename FuncType>
    void operator () (FuncType &f, std::vector<int> &args){
        assert(args.size() == num_args); // just to be sure
        call(f, args, BuildIndices<num_args>{});
    }
};

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

@Fernandes Это именно то, что я ищу. Danqi Wang
Я думаюassert следует использовать>= скорее, чем==, какassert(args.size() >= num_args);, Это более гибкий!
@Fernandes У меня есть только g ++ - 4.5, который не поддерживает псевдоним шаблона, поэтому я используюtypedef вместо. Вoperator () я должен сделатьtypedef typename build_indices<num_args>::type idx_type; call(f, args, idx_type{});, Есть лучшее решение? Danqi Wang
@Fernandes На самом деле можно удалить параметр шаблонаnum_args используяboost::function_traits<FuncType>::arity вopertor (), Но я прочитал реализациюboost::function_traitsКажется, он поддерживает только до 11 аргументов. Я думаю, что стоит сохранитьnum_args сделать это вообще. Danqi Wang

Похожие вопросы