почти Boost.Lambda в C++11
От: jazzer Россия Skype: enerjazzer
Дата: 30.10.13 03:11
Оценка: 76 (9) :)
Тут в процессе очередной дискуссии "С++ против всех" родился пример реализации полиморфной (т.е. шаблонной) лямбды в духе Boost.Lambda в три строчки на С++11.
Решил, что тут тоже многим будет интересно:
#include <functional>
#define JUST_RETURN(...) decltype( __VA_ARGS__ ) { return __VA_ARGS__; }
#define OP(name,op) struct name {                                            \
  template<class X, class Y>auto operator()(X x, Y y) -> JUST_RETURN(x op y) \
};                                                                           \
template<class X, class Y>auto operator op(X x, Y y) -> JUST_RETURN(std::bind(name(), x, y))

OP(Mul, *)
// и т.д. для остальных операторов

  полный код с тестом
#include <functional>
#include <iostream>
#include <string> // for "Hello, world!"

#define JUST_RETURN(...) decltype( __VA_ARGS__ ) { return __VA_ARGS__; }
#define OP(name,op) struct name {                                            \
  template<class X, class Y>auto operator()(X x, Y y) -> JUST_RETURN(x op y) \
};                                                                           \
template<class X, class Y>auto operator op(X x, Y y) -> JUST_RETURN(std::bind(name(), x, y))

OP(Mul, *)
OP(Div, /)
OP(Mod, %)
OP(Add, +)
OP(Sub, -)
OP(EQ, ==)
OP(LT, < )
OP(LE, <=)
OP(GT, > )
OP(GE, >=)

int main()
{
  using namespace std;
  using namespace std::placeholders;

  cout << ( 9 * _1)(5)          << endl;                     // 45
  cout << (_1 *  8)(5)          << endl;                     // 40
  cout << (_1 * _1)(5)          << endl;                     // 25
  cout << (_1 * _2)(5,6)        << endl;                     // 30
  cout << (_1 + _2 * _3)(5,6,7) << endl;                     // 47 (42+5)
  cout << (_3 - _2 * _1)(5,6,7) << endl;                     // -23 (7-30)
  cout << ( 9 * _2)(5,6)        << endl;                     // 54
  cout << (_2+", "+_1+"!")("world",string("Hello")) << endl; // "Hello, world!"
}
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.