c ++, как объединить кортежи std :: bind и variadi c? - PullRequest
1 голос
/ 06 марта 2020

похожие сообщения: Как объединить шаблоны std :: bind (), variadi c и совершенную пересылку?

Есть ли способ связать функцию с variadi c кортежи? Здесь неправильный код, указывающий намерение:

// t is an instance of T
auto f = std::bind(&T::iterate,t,???);
// args is an instance of std::tuple<Args...> args;
std::apply(f,args);

(примечание: я не уверен, что «variadi c tuple» является правильной терминологией. Ждем редактирования сообщения с вашей поправкой)

Ответы [ 2 ]

3 голосов
/ 06 марта 2020

Начиная с C ++ 20 вы можете использовать std :: bind_front :

template<class T>
void print (T val) {
    std::cout << val << std::endl;
}

struct T {
    template<class ... Args>
    void iterate(Args... args) {
        int temp[] = { (print(args),0)... };
    }
};

// all happens here
template<class ... Args>
void foo(const tuple<Args...>& args) {
    T t;
    auto f = std::bind_front(&T::iterate<Args...>,&t);
    std::apply(f,args);
}

// the call 
int i = 1;
foo(std::make_tuple(i,i+1,"bind is cool"));

Если вы хотите использовать старый std :: bind , вы можете укажите собственные заполнители, которые будут сгенерированы из пакета:

template<int N>
struct MyPlaceholder {};

namespace std {
    template<int N>
    struct is_placeholder<MyPlaceholder<N>> : public integral_constant<int, N> {};
}

template<class ... Args, size_t ... Indices>
void foo2helper(const tuple<Args...>& args, std::index_sequence<Indices...>) {
    T t;
    auto f = std::bind(&T::iterate<Args...>,&t, (MyPlaceholder<Indices+1>{})...);
    std::apply(f,args);
}

template<class ... Args>
void foo2(const tuple<Args...>& args) {
    foo2helper(args, std::make_index_sequence<sizeof...(Args)>{});
}
// the call
foo2(std::make_tuple(2.34,"only bind"));

Демо-версия

2 голосов
/ 06 марта 2020

Не используйте bind, используйте вместо этого лямбду:

auto f = [&t](auto... args){ t.iterate(args...); };
std::apply(f, args);

Если вы хотите совершенную пересылку, это будет выглядеть так:

auto f = [&t](auto&&... args){ t.iterate(std::forward<decltype(args)>(args)...); };
std::apply(f, args);
...