связать первый аргумент функции, не зная ее арности

Я хотел бы иметь функцию BindFirst это связывает первый аргумент функции без необходимости явно знать / указывать арность функции, используя std :: placeholder. Я бы хотел, чтобы код клиента выглядел примерно так.

#include <functional>
#include <iostream>

void print2(int a, int b)
{
std::cout << a << std::endl;
std::cout << b << std::endl;
}

void print3(int a, int b, int c)
{
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << c << std::endl;
}

int main()
{
auto f = BindFirst(print2, 1); // std::bind(print2, 1, std::placeholders::_1);
auto g = BindFirst(print3, 1); // std::bind(print3, 1, std::placeholders::_1, std::placeholders::_2);
f(2);
g(2,3);
}

Любые идеи, как BindFirst может быть реализовано?

7

Решение

В C ++ 11:

#include <type_traits>
#include <utility>

template <typename F, typename T>
struct binder
{
F f; T t;
template <typename... Args>
auto operator()(Args&&... args) const
-> decltype(f(t, std::forward<Args>(args)...))
{
return f(t, std::forward<Args>(args)...);
}
};

template <typename F, typename T>
binder<typename std::decay<F>::type
, typename std::decay<T>::type> BindFirst(F&& f, T&& t)
{
return { std::forward<F>(f), std::forward<T>(t) };
}

ДЕМО 1

В C ++ 14:

#include <utility>

template <typename F, typename T>
auto BindFirst(F&& f, T&& t)
{
return [f = std::forward<F>(f), t = std::forward<T>(t)]
(auto&&... args)
{ return f(t, std::forward<decltype(args)>(args)...); };
}

ДЕМО 2

9

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]