Использование устаревших связывателей и лямбда-выражений C ++ 0x - PullRequest
3 голосов
/ 07 апреля 2010

C ++ 0x устарел использовать старые связующие, такие как bind1st и bind2nd, в пользу универсальных std::bind. C ++ 0x лямбды хорошо связываются с std::bind, но они не связываются с классическими bind1st и bind2nd, потому что по умолчанию лямбды не имеют вложенных типов, таких как argument_type, first_argument_type, second_argument_type и result_type , Поэтому я подумал, что std::function может служить стандартным способом привязки лямбд к старым папкам, поскольку он предоставляет необходимые typedefs.

Тем не менее, использование std::function сложно использовать в этом контексте, потому что оно заставляет вас указывать тип функции при ее создании.

auto bound = 
  std::bind1st(std::function<int (int, int)>([](int i, int j){ return i < j; }), 10); // hard to use
auto bound = 
  std::bind1st(std::make_function([](int i, int j){ return i < j; }), 10); // nice to have but does not compile.

Я не смог найти удобный генератор объектов для std::function. Что-то вроде std::make_fuction было бы неплохо иметь. Существует ли такая вещь? Если нет, есть ли какой-нибудь другой лучший способ связать лямды с классическими связующими веществами?

Ответы [ 2 ]

2 голосов
/ 08 апреля 2010

Никогда не пытался сделать такую ​​вещь, и у меня нет времени, чтобы дать полный ответ, но я предполагаю, что что-то можно сделать с Boost.FunctionTypes.

Вот примерный, неполный и непроверенный черновик, чтобы дать вам представление:

template <typename T>
struct AdaptedAsUnary : T
{
    namespace bft = boost::function_types;
    namespace bmpl = boost::mpl;

    typedef typename bft::result_type<T>::type result_type;
    typedef typename bmpl::front<typename bft::parameter_types<T>::type>::type argument_type;

    AdaptedAsUnary(T t) : T(t) {}
};

template <typename T>
AdaptedAsUnary<T>
AdaptAsUnary(T t)
{
    return AdaptedAsUnary<T>(t);
}
1 голос
/ 25 июня 2011

Я не знаю, почему вы все еще нуждаетесь в bind1st и т. Д. Единственное, о чем я могу подумать - это поддерживать старый код. На самом деле, bind1st(f, a) можно заменить на [a](v){ return f(a, v); } и т. Д., И это универсальное решение.

...