Язык C++ Лекция 2
Недостатки enumов Засорение namespaceа, в котором находится enum Соответственно, члены enumа должны иметь уникальный префикс.
Enum class struct MyEnum { enum Type { Value1, Value2, Value3 }; MyEnum() : _value() { } MyEnum(Type value) : _value(value) { } operator Type&() { return _value; } operator Type() const { return _value; } private: Type _value; };
Enum class #define DECLARE_ENUM_CLASS(ClassName) \ ClassName () : _value() { } \ ClassName(Type value) : _value() { } \ operator Type&() { return _value; } \ operator Type() const { return _value; } \ private: \ Type _value; struct MyEnum { enum Type { Value1, Value2, Value3 }; DECLARE_ENUM_CLASS(MyEnum); };
Enum class void g(MyEnum val) { std::cout
Лямбда-исчисление
Абстракция (λ-абстракция) - строит функции по заданным выражениям. Именно, если t = t[x] выражение, свободно содержащее x, λx.t[x] обозначает функцию. Аппликация – применение или вызов функции по отношению к заданному значению ( f a ).
β-редукция λx.2 * x + 1 – абстракция (λx.2 * x + 1) 3 – аппликация (подстановка числа 3 в терм 2 * x + 1) (λx.t) a – применение абстракции к некому терму называется редексом (redex) Частичная аппликация (каррирование) по сути является β-редукцией. Вместе с β-редукцией лямбда-исчисление обладает полнотой по Тьюрингу.
Свободные и связанные переменные λx. λy.(x + y)/2 – функция двух переменных Для внутренней функции λy.(x + y)/2: x – свободная переменная, y – связанная. Для внешней функции обе переменные являются связанными
Lambda в языке Python make_adder = lambda x: ( lambda n: ( x + n ) f = make_adder(10) print f(5) # 15 print f(-1) # 9
boost::lambda Lifes good =)
Lambda в boost boost::function make_adder(int x) { using namespace boost::lambda; return _1 + x; // λn.n+x } int main() { boost::function f = make_adder(10); std::cout
Пример использования using namespace boost::lambda; std::vector a(20); generate( a.begin(), a.end(), &rand ); for_each (a.begin (), a.end (), std::cout
Как это работает? class placeholder1 {}; template std::binder2nd > operator < (placeholder1, T val) { return std::bind2nd(std::less (), val); } template std::binder1st > operator < (T val, placeholder1) { return std::bind1st(std::less (), val); }
Как это работает? placeholder1 _1; int main() { std::vector vec(10); std::generate(vec.begin(), vec.end(), &rand); std::for_each(vec.begin(), vec.end(),print_t ()); std::cout
Возможности boost::lambda bind – каррирование аргументов ret - переопределение возвращаемого типа constant, ref, var – использование локального контекста If_then, if_then_else, while_loop, for_loop, switch_case, и т.д. – управляющие структуры try_catch, constructor, destructor, new_ptr/array, delete_ptr/array, ll_sizeof, ll_typeid… и многое другое
Списки типов Life is better =]
Обычный список struct Node { intData; Node*Next; Node(int data, Node* next) : Data(data), Next(next) { } }; Node *my_list = new Node(3, new Node(5, new Node(1, NULL)));
Простейший список типов struct EndListNode { }; template struct Node { typedef Data Data; typedef Next Next; }; typedef Node >> MyList;
Удобный синтаксис typedef EndListNode TypeList_0; template class TypeList_1 : public Node { }; template class TypeList_2 : public Node > { }; template class TypeList_3 : public Node > { }; typedef TypeList_3 MyList;
Пример алгоритма struct EndListNode { //... template struct Get { static const int Value = ERROR_type_list_index_out_of_range; }; }; template struct Node { //... template struct Get { typedef typename Next::Get ::Value Value; }; template struct Get { typedef Data Value; }; }; typedef TypeList_3 MyList; typedef MyList::Get ::Value SomeType;
Простейший кортеж template class Tuple { typedef typename TypeList::Data Data; typedef typename TypeList::Next Tail; Data_data; Tuple _tail; public: Tuple() { } template Tuple(T1 p1) : _data(p1) { } template Tuple(T1 p1, T2 p2) : _data(p1), _tail(p2) { } template Tuple(T1 p1, T2 p2, T3 p3) : _data(p1), _tail(p2, p3) { } };
Простейший кортеж template class Tuple { }; Tuple tuple(42, "Hello, world!", );
Кортежи template class Tuple { //... template typename TypeList::Get ::Value& Get() { return _tail.Get (); } template Data& Get () { return _data; } }; Tuple tuple(42, "Hello, world!", ); double d = tuple.Get ();
Применение кортежей template std::string to_string_impl(const TupleType& tuple) { std::strstream stream; stream
Применение кортежей template std::string to_string(const T1& p1) { return to_string_impl(make_tuple(p1)); } template std::string to_string(const T1& p1, const T2& p2) { return to_string_impl(make_tuple(p1, p2)); } template std::string to_string(const T1& p1, const T2& p2, const T3& p3) { return to_string_impl(make_tuple(p1, p2, p3)); }
Применение кортежей template Tuple > make_tuple(const T1& p1) { return Tuple >(p1); } template Tuple > make_tuple(const T1& p1, const T2& p2) { return Tuple >(p1, p2); } template Tuple > make_tuple(const T1& p1, const T2& p2, const T3& p3) { return Tuple >(p1, p2, p3); }
Применение кортежей void test_func() { int i = 42; std::string str = to_string( (char*) "i = ", i, '.' ); std::cout