2010-04-07 3 views
3

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

Однако использование 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 было бы неплохо иметь. Существует ли такая вещь? Если нет, есть ли другой лучший способ привязки ламд к классическим связующим?

+0

Обратите внимание, что использование классических связующих с lambdas может быть полезно для устаревших библиотек, которые ожидают, что их типы объектов функций будут раскрывать вышеупомянутые typedefs. Поэтому я не думаю, что ванильные лямбды можно использовать с такими библиотеками. – Sumant

ответ

2

Никогда не пытался это делать, и у меня нет времени, чтобы дать полный ответ, но я думаю, что что-то можно было бы сделать с помощью 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

Это аккуратное решение. Наследование от лямбда-типа является новым для меня и прекрасно работает на g ++ 4.5. Хотя на сегодняшний день boost :: function_types (1.42) не поддерживает lambdas как встроенный вызываемый тип, я мог бы найти выход. В будущем, когда они его поддержат (надеюсь), это решение можно использовать как есть. На данный момент я использовал ответ для http://stackoverflow.com/questions/2562320/specializing-a-template-on-a-lambda-in-c0x в качестве замены возможностей интроспекции boost :: function_types. Используя эти функции_трассы для лямбда, выполняется множественное наследование от T и std :: unary_function. – Sumant

1

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

 Смежные вопросы

  • Нет связанных вопросов^_^