├── 02_basic_template ├── 01_template_stack.cpp ├── 02_separate_implementation.cpp ├── 03_member_template.cpp ├── 04_class_and_member_template.cpp ├── 05_alias_templates.cpp ├── 06_main.cpp ├── 06_stack.cpp ├── 06_stack.h ├── 07_explicit_instantiation_member_function.cpp ├── 08_default_template_arg_function.cpp ├── 09_default_template_arg_class.cpp ├── 10_fixed_capacity_stack.cpp ├── 11_array_utility.cpp ├── 12_property.cpp ├── 13_constructor_template.cpp ├── 14_typename_keyword.cpp ├── 15_template_keyword.cpp ├── 16_specialize_function_template.cpp ├── 17_specialize_class_template.cpp ├── 18_partial_specialize.cpp ├── 19_overload_instead_of_partial_specialize.cpp ├── 20_template_template_parameter.cpp ├── 21_variadic_print.cpp ├── 22_tuple.cpp └── 23_initialize.cpp ├── 03_generic_programming ├── 01_find.cpp ├── 02_copy_01.cpp ├── 02_copy_02.cpp ├── 03_find_if_01.cpp ├── 03_find_if_02.cpp ├── 04_selection_sort.cpp ├── 05_print_all.cpp ├── 06_back_inserter.cpp ├── 07_advance.cpp ├── 08_decoration_01.cpp ├── 08_decoration_02.cpp └── 09_print_on.cpp ├── 04_template_meta_programming ├── 01_increment.cpp ├── 02_factorial.cpp ├── 03_square.cpp ├── 04_pow.cpp ├── 05_identity.cpp ├── 06_add_pointer.cpp ├── 07_add_lvalue_reference.cpp ├── 08_separate_meta_function.cpp ├── 09_combine_meta_function.cpp ├── 10_remove_const.cpp ├── 11_remove_cv.cpp ├── 12_if.cpp ├── 13_high_order_if.cpp ├── 14_cpp11_meta_func_00.cpp ├── 15_cpp11_meta_func_01.cpp ├── 16_cpp11_meta_func_02.cpp ├── 17_cpp11_meta_func_03.cpp ├── 18_type_list_00_head_tail.cpp ├── 19_type_list_01_any_of.cpp ├── 20_type_list_02_any_of_improve.cpp └── 21_type_list_03_transform.cpp ├── 05_sfinae ├── 01_introduction_sfinae.cpp ├── 02_is_void.cpp ├── 03_is_pointer.cpp ├── 04_has_iterator_function.cpp ├── 05_has_iterator_metafunction.cpp ├── 06_has_iterator_03_metafunction.cpp ├── 07_has_iterator_decltype.cpp ├── 08_is_class.cpp ├── 09_is_assignable.cpp ├── 10_is_addable.cpp ├── 11_enable_if.cpp ├── 12_has_add_member.cpp ├── 13_enable_if_default_template_argument.cpp ├── 14_sort.cpp ├── 15_optimized_copy.cpp └── 16_optimized_dtor.cpp ├── 06_policy ├── 01_policy_based_logger.cpp ├── 02_default_policy.cpp ├── 03_policy_based_smart_ptr.cpp ├── 04_inheritance_boost_multi_index.cpp ├── 05_named_tmpl_param │ ├── 1st_step.cpp │ ├── 2nd_step.cpp │ ├── find_if.hpp │ └── named_tmpl_param.hpp └── 06_sorted_vector.cpp ├── 07_concept ├── 01_min_requirements.cpp ├── 02_basic_distance.cpp ├── 03_concept_based_distance.cpp ├── 04_add_my_point.cpp ├── 05_concept_based_overload.cpp └── 06_specialize_template_with_concept.cpp ├── 08_type_erasure ├── 01_virtual_function_table.cpp ├── 02_non_template_base_and_template_derived.cpp ├── 03_shared_ptr_implementation.cpp ├── 04_any_implementation.cpp ├── 05_1st_step_function_implementation.cpp ├── 06_2nd_step_function_implementation.cpp └── 07_simple_type_erasure.cpp ├── 09_crtp ├── 01_basic_crtp.cpp ├── 02_equal_comparable.cpp ├── 03_less_than_comparable.cpp └── 04_enable_shared_from_this.cpp ├── 10_template_conversion_operator ├── 01_operator_bool.cpp ├── 02_for_each_macro.cpp ├── 03_result_type_overload.cpp ├── 04_template_convertion_operator.cpp ├── 05_container_holder.cpp └── 06_auto_deduction_lexical_cast.cpp ├── 11_expression_template ├── 01_plus_expression.cpp ├── 02_multiply_expression.cpp └── 03_expression_design.cpp └── README.md /02_basic_template/01_template_stack.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | class Stack { 7 | T* data_; 8 | int index_; 9 | int capacity_; 10 | public: 11 | explicit Stack(int n) : capacity_(n), index_(0) 12 | { data_ = new T[capacity_]; } 13 | ~Stack() 14 | { delete[] data_; } 15 | void push(T x) 16 | { if (index_ < capacity_) data_[index_++] = x; } 17 | T top() const 18 | { return data_[index_ - 1]; } 19 | void pop() 20 | { if (index_ > 0) --index_; } 21 | }; 22 | 23 | // 3種のStackを使う…… 24 | int main() 25 | { 26 | Stack istack(5); 27 | Stack lstack(8); 28 | Stack pstack(10); 29 | istack.push(1); 30 | istack.push(2); 31 | //…… 32 | } 33 | -------------------------------------------------------------------------------- /02_basic_template/02_separate_implementation.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | class Stack { 7 | T* data_; 8 | int index_; 9 | int capacity_; 10 | public: 11 | explicit Stack(int n); 12 | ~Stack(); 13 | void push(T x); 14 | T top() const; 15 | void pop(); 16 | }; 17 | 18 | template 19 | Stack::Stack(int n) : capacity_(n), index_(0) 20 | { 21 | data_ = new T[capacity_]; 22 | } 23 | 24 | template 25 | Stack::~Stack() 26 | { 27 | delete[] data_; 28 | } 29 | 30 | template 31 | void Stack::push(T x) 32 | { 33 | if (index_ < capacity_) data_[index_++] = x; 34 | } 35 | 36 | template 37 | T Stack::top() const 38 | { 39 | return data_[index_ - 1]; 40 | } 41 | 42 | template 43 | void Stack::pop() 44 | { 45 | if (index_ > 0) 46 | --index_; 47 | } 48 | 49 | // 3種のStackを使う…… 50 | int main() 51 | { 52 | Stack istack(5); 53 | Stack lstack(8); 54 | Stack pstack(10); 55 | istack.push(1); 56 | istack.push(2); 57 | //…… 58 | } 59 | -------------------------------------------------------------------------------- /02_basic_template/03_member_template.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | 7 | class Foo { 8 | int value_; 9 | public: 10 | Foo(int v) : value_(v) {} 11 | 12 | template 13 | void get(T& dst) const 14 | { 15 | dst = value_; 16 | } 17 | 18 | //…… 19 | }; 20 | 21 | 22 | int main() 23 | { 24 | Foo f(3); 25 | long v; 26 | f.get(v); 27 | 28 | std::cout << v << std::endl; 29 | } 30 | -------------------------------------------------------------------------------- /02_basic_template/04_class_and_member_template.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | 7 | template 8 | class Stack { 9 | T* data_; 10 | int index_; 11 | int capacity_; 12 | public: 13 | explicit Stack(int n); 14 | ~Stack(); 15 | void push(T x); 16 | 17 | template 18 | void top(U& dst) const; 19 | 20 | void pop(); 21 | }; 22 | 23 | template 24 | Stack::Stack(int n) : capacity_(n), index_(0) 25 | { 26 | data_ = new T[capacity_]; 27 | } 28 | 29 | template 30 | Stack::~Stack() 31 | { 32 | delete[] data_; 33 | } 34 | 35 | template 36 | void Stack::push(T x) 37 | { 38 | if (index_ < capacity_) data_[index_++] = x; 39 | } 40 | 41 | template 42 | template 43 | void Stack::top(U& dst) const 44 | { 45 | dst = data_[index_ - 1]; 46 | } 47 | 48 | template 49 | void Stack::pop() 50 | { 51 | if (index_ > 0) 52 | --index_; 53 | } 54 | 55 | int main() 56 | { 57 | const int n = 1; 58 | Stack s(n); 59 | s.push('A'); 60 | 61 | int i; 62 | long l; 63 | 64 | s.top(i); 65 | s.top(l); 66 | 67 | std::cout << static_cast(i) << std::endl; 68 | std::cout << static_cast(l) << std::endl; 69 | } 70 | -------------------------------------------------------------------------------- /02_basic_template/05_alias_templates.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | class Stack { 7 | T* data_; 8 | int index_; 9 | int capacity_; 10 | public: 11 | explicit Stack(int n) : capacity_(n), index_(0) 12 | { 13 | Allocator alloc; 14 | data_ = alloc.allocate(capacity_); 15 | for (int i = 0; i < capacity_; ++i) { 16 | alloc.construct(data_ + i); 17 | } 18 | } 19 | ~Stack() 20 | { delete[] data_; } 21 | void push(T x) 22 | { if (index_ < capacity_) data_[index_++] = x; } 23 | T top() const 24 | { return data_[index_ - 1]; } 25 | void pop() 26 | { if (index_ > 0) --index_; } 27 | }; 28 | 29 | #include 30 | 31 | template 32 | using MyAllocator = std::allocator; 33 | 34 | // カスタムアロケータを使用するStack型 35 | template 36 | using MyStack = Stack>; 37 | 38 | int main() 39 | { 40 | // 要素型のみ後から指定する 41 | const int n = 3; 42 | MyStack s(n); 43 | } 44 | -------------------------------------------------------------------------------- /02_basic_template/06_main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include "06_stack.h" 7 | 8 | int main() 9 | { 10 | Stack s(10); 11 | s.push(1); 12 | s.push(2); 13 | while (s.size() != 0) { 14 | std::cout << s.top() << std::endl; 15 | s.pop(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /02_basic_template/06_stack.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include "06_stack.h" 6 | 7 | template 8 | Stack::Stack(int n) : capacity_(n), index_(0) 9 | { 10 | data_ = new T[capacity_]; 11 | } 12 | 13 | template 14 | Stack::~Stack() 15 | { 16 | delete[] data_; 17 | } 18 | 19 | template 20 | void Stack::push(T x) 21 | { 22 | if (index_ < capacity_) { 23 | data_[index_++] = x; 24 | } 25 | } 26 | 27 | template 28 | T Stack::top() const 29 | { 30 | return data_[index_ - 1]; 31 | } 32 | 33 | template 34 | void Stack::pop() 35 | { 36 | if (index_ > 0) { 37 | --index_; 38 | } 39 | } 40 | 41 | template 42 | int Stack::size() const 43 | { 44 | return index_; 45 | } 46 | 47 | template class Stack; 48 | -------------------------------------------------------------------------------- /02_basic_template/06_stack.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #ifndef STACK_H_ 6 | #define STACK_H_ 7 | 8 | template 9 | class Stack { 10 | T* data_; 11 | int index_; 12 | int capacity_; 13 | public: 14 | explicit Stack(int n); 15 | ~Stack(); 16 | 17 | void push(T x); 18 | T top() const; 19 | void pop(); 20 | int size() const; 21 | }; 22 | #endif 23 | -------------------------------------------------------------------------------- /02_basic_template/07_explicit_instantiation_member_function.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | 8 | template 9 | class Util { 10 | T value_; 11 | public: 12 | Util(const T& v); 13 | void add(const T& v); 14 | T get() const; 15 | int size() const; 16 | }; 17 | 18 | template 19 | Util::Util(const T& v) : value_(v) {} 20 | 21 | template 22 | void Util::add(const T& v) { value_ += v; } 23 | 24 | template 25 | T Util::get() const { return value_; } 26 | 27 | template 28 | int Util::size() const { return value_.size(); } 29 | 30 | 31 | // クラス全体を明示的にインスタンス化する 32 | // template class Util; // コンパイルエラー!intはsize()メンバ関数を持っていない 33 | 34 | // 個々のメンバ関数を明示的にインスタンス化する 35 | // OK 36 | template Util::Util(const int&); 37 | template void Util::add(const int&); 38 | template int Util::get() const; 39 | 40 | int main() 41 | { 42 | Util iu(12); 43 | iu.add(34); 44 | std::cout << iu.get() << std::endl; 45 | Util su("hello, "); 46 | su.add("C++"); 47 | std::cout << su.get() << std::endl; 48 | } 49 | -------------------------------------------------------------------------------- /02_basic_template/08_default_template_arg_function.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | 8 | template // 省略時はdoubleとみなす 9 | T pi() { return T(3.1415926536); } 10 | 11 | int main() 12 | { 13 | float x = pi(); // 型の明示 14 | double y = pi<>(); // 省略時 : pi() 15 | double z = pi(); // 同上 16 | 17 | std::cout << std::setprecision(10) << std::fixed; 18 | std::cout << x << std::endl; 19 | std::cout << y << std::endl; 20 | std::cout << z << std::endl; 21 | } 22 | -------------------------------------------------------------------------------- /02_basic_template/09_default_template_arg_class.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | 8 | template 9 | struct xyz { 10 | X x; 11 | Y y; 12 | Z z; 13 | }; 14 | 15 | int main() 16 | { 17 | xyz<> s0; // → xyz 18 | xyz s1; // → xyz 19 | xyz s2; // → xyz 20 | xyz s3; // → xyz 21 | } 22 | -------------------------------------------------------------------------------- /02_basic_template/10_fixed_capacity_stack.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | class Stack { 7 | T data_[N]; 8 | int index_; 9 | public: 10 | Stack() : index_(0) {} 11 | ~Stack() {} 12 | void push(T x) 13 | { if (index_ < N) data_[index_++] = x; } 14 | T top() const 15 | { return data_[index_ - 1]; } 16 | void pop() 17 | { if (index_ > 0) --index_; } 18 | }; 19 | 20 | // 3種のStackを使う…… 21 | int main() 22 | { 23 | Stack istack; 24 | Stack lstack; 25 | Stack pstack; // 省略時は10 26 | //…… 27 | } 28 | 29 | -------------------------------------------------------------------------------- /02_basic_template/11_array_utility.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | 7 | template 8 | int size(T (&ar)[N]) 9 | { 10 | return N; 11 | } 12 | 13 | template 14 | T last_element(T (&ar)[N]) 15 | { 16 | return ar[N - 1]; 17 | } 18 | 19 | int main() 20 | { 21 | int data[] = { 1, 3, 5, 7, 9 }; 22 | int n = size(data); // 5を返す 23 | int last = last_element(data); // data[4]を返す 24 | 25 | std::cout << n << std::endl; 26 | std::cout << last << std::endl; 27 | } 28 | -------------------------------------------------------------------------------- /02_basic_template/12_property.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | /* 6 | N1615: C++ Properties -- a Library Solution 7 | http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1615.pdf 8 | より抜粋 9 | */ 10 | 11 | template // set 関数 14 | class RWProperty { 15 | Object* my_object; 16 | public: 17 | // プロパティのオーナー(所有者) を設定 18 | void operator()(Object* obj) { my_object = obj; } 19 | // 関数呼び出しによるget/set 20 | T operator()() const 21 | { return (my_object->*real_getter)(); } 22 | T operator()(const T& value) 23 | { return (my_object->*real_setter)(value); } 24 | // メンバ関数get/set 25 | T get() const 26 | { return (my_object->*real_getter)(); } 27 | T set(const T& value) 28 | { return (my_object->*real_setter)(value); } 29 | // '='演算子によるアクセス 30 | operator T() const 31 | { return (my_object->*real_getter)(); } 32 | T operator=(const T& value) 33 | { return (my_object->*real_setter)(value); } 34 | typedef T value_type; 35 | }; 36 | 37 | #include 38 | #include 39 | 40 | using namespace std; 41 | 42 | class Cat { 43 | private: 44 | int age_; 45 | string name_; 46 | int set_age(const int& age) { return age_ = age; } 47 | int get_age()const { return age_; } 48 | string set_name(const string& name) { return name_ = name; } 49 | string get_name()const { return name_; } 50 | public: 51 | RWProperty age; 52 | RWProperty name; 53 | Cat() { age(this); name(this); } 54 | }; 55 | 56 | int main() 57 | { 58 | Cat aCat; 59 | aCat.age = 4; 60 | aCat.name = "tama"; 61 | int age = aCat.age; 62 | string name = aCat.name; 63 | cout << name << " is " << age << " years old.\n"; 64 | } 65 | -------------------------------------------------------------------------------- /02_basic_template/13_constructor_template.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | 7 | template 8 | class Point { 9 | template friend class Point; 10 | private: 11 | T x_; 12 | T y_; 13 | public: 14 | // これがコンストラクタテンプレート 15 | template 16 | Point(const Point& r) : x_(r.x_), y_(r.y_) {} 17 | 18 | Point(T x = T(), T y = T()) : x_(x), y_(y) {} 19 | Point(const Point& pt) : x_(pt.x_), y_(pt.y_) {} 20 | void print(std::ostream& s) const 21 | { return s << '(' << x_ << ',' << y_ << ')'; } 22 | }; 23 | 24 | 25 | int main() 26 | { 27 | Point ip(12, 34); 28 | Point lp(ip); 29 | } 30 | -------------------------------------------------------------------------------- /02_basic_template/14_typename_keyword.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | struct X { 6 | typedef int result; 7 | result f(); 8 | //…… 9 | }; 10 | 11 | struct Y { 12 | static const int result = 5; 13 | //…… 14 | }; 15 | 16 | int p; 17 | 18 | template 19 | void g(T arg) 20 | { 21 | typename T::result* p; 22 | //…… 23 | } 24 | 25 | int main() 26 | { 27 | g(X()); // OK 28 | //g(Y()); // コンパイルエラー!Yはresult型を持っていない 29 | } 30 | -------------------------------------------------------------------------------- /02_basic_template/15_template_keyword.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | 7 | class utility { 8 | public: 9 | template 10 | int get(int arg) 11 | { 12 | return N + arg; 13 | } 14 | }; 15 | 16 | template 17 | int foo(T x, int n) 18 | { 19 | return x.template get<3>(n); 20 | } 21 | 22 | int main() 23 | { 24 | std::cout << foo(utility(), 2) << std::endl; 25 | } 26 | -------------------------------------------------------------------------------- /02_basic_template/16_specialize_function_template.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include // strcmp 7 | 8 | template 9 | bool equal(T x, T y) 10 | { 11 | return x == y; 12 | } 13 | 14 | template <> 15 | bool equal(const char* x, const char* y) 16 | { 17 | return std::strcmp(x, y) == 0; 18 | } 19 | 20 | int main() 21 | { 22 | int n = 3; 23 | const char* s = "C++"; 24 | std::cout << std::boolalpha; 25 | std::cout << equal(n, 2) << std::endl; 26 | std::cout << equal(n, 3) << std::endl; 27 | std::cout << equal(s, "Java") << std::endl; 28 | std::cout << equal(s, "C++") << std::endl; 29 | } 30 | -------------------------------------------------------------------------------- /02_basic_template/17_specialize_class_template.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | 8 | // プライマリテンプレート 9 | template 10 | class printer { 11 | public: 12 | void out(const T& value) const 13 | { 14 | std::cout << value; 15 | } 16 | }; 17 | 18 | // std::string に対する特殊化 19 | template <> 20 | class printer { 21 | public: 22 | void out(const std::string& value) const 23 | { 24 | // 文字列は "" で囲む 25 | std::cout << '"' << value << '"'; 26 | } 27 | }; 28 | 29 | int main() 30 | { 31 | printer().out(3); 32 | std::cout << std::endl; 33 | printer().out("hello"); 34 | } 35 | -------------------------------------------------------------------------------- /02_basic_template/18_partial_specialize.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | template 11 | class printer { 12 | public: 13 | // 標準出力に出力 14 | void out(T value) 15 | { 16 | std::cout << value << std::endl; 17 | } 18 | }; 19 | 20 | // ポインタに対する部分特殊化 21 | template 22 | class printer { 23 | public: 24 | void out(T* value) const 25 | { 26 | std::cout << *value << std::endl; 27 | } 28 | }; 29 | 30 | int main() 31 | { 32 | printer prt; // 部分特殊化版がインスタンス化される 33 | int n = 123; 34 | prt.out(&n); // &nが指す値(123)が出力される 35 | } 36 | 37 | -------------------------------------------------------------------------------- /02_basic_template/19_overload_instead_of_partial_specialize.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | 7 | template 8 | void print(T value) { std::cout << value << std::endl; } // [1] 9 | 10 | template 11 | void print(T* value) { std::cout << *value << std::endl; } // [2] 12 | 13 | int main() 14 | { 15 | int n = 123; 16 | print(n); // [1]が呼ばれる 17 | print(&n); // [2]が呼ばれる 18 | } 19 | -------------------------------------------------------------------------------- /02_basic_template/20_template_template_parameter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | template > 15 | class Container> 16 | class Phonebook { 17 | struct Record { 18 | string name; 19 | string phone; 20 | Record(const string& n, const string& p) : name(n), phone(p) {} 21 | friend ostream& operator<<(ostream& stream, const Record& r) 22 | { 23 | return stream << r.name << ':' << r.phone; 24 | } 25 | }; 26 | Container book; 27 | public: 28 | void add(const string& name, const string& phone) 29 | { 30 | book.emplace_back(name,phone); 31 | } 32 | 33 | void print(ostream& stream) const 34 | { 35 | copy(begin(book), end(book), 36 | ostream_iterator(stream, "\n")); 37 | } 38 | }; 39 | 40 | int main() 41 | { 42 | Phonebook pb; // list,deque も指定可能 43 | pb.add("police", "110"); 44 | pb.add("fire", "119"); 45 | pb.add("weather", "177"); 46 | pb.print(std::cout); 47 | } 48 | -------------------------------------------------------------------------------- /02_basic_template/21_variadic_print.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | void printType() 11 | { 12 | cout << endl; 13 | } 14 | 15 | template 16 | void printType(Thead head, Tbody... body) 17 | { 18 | cout << '(' << typeid(Thead).name() << ')' << head; 19 | if (sizeof...(body) > 0) cout << ','; 20 | printType(body...); 21 | } 22 | 23 | int main() 24 | { 25 | printType('T', 4, "two"); 26 | } 27 | 28 | /* 実行結果 29 | Visual C++: 30 | (char)T, (int)4,(char const*)two 31 | g++: 32 | (c)T,(i)4,(PKc)two 33 | */ 34 | -------------------------------------------------------------------------------- /02_basic_template/22_tuple.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | 8 | using std::cout; 9 | using std::endl; 10 | 11 | void printType() 12 | { 13 | cout << endl; 14 | } 15 | 16 | template 17 | void printType(Thead head, Tbody... body) 18 | { 19 | cout << '(' << typeid(Thead).name() << ')' << head; 20 | if (sizeof...(body) > 0) cout << ','; 21 | printType(body...); 22 | } 23 | 24 | /* 25 | * tuple 26 | */ 27 | template 28 | struct tuple_data; 29 | 30 | // [1] 31 | template 32 | struct tuple_data {}; 33 | 34 | // [2] 35 | template 36 | struct tuple_data : public tuple_data { 37 | Thead value; 38 | }; 39 | 40 | // [3] 41 | template 42 | struct tuple : public tuple_data<0, Ts...> {}; 43 | 44 | /* 45 | struct tuple<○, △, □> 46 | : tuple_data<0, ○, △, □> {} 47 | : tuple_data<1, △, □> { ○ value; } 48 | : tuple_data<2, □> { △ value; } 49 | : tuple_data<3> { □ value; } 50 | */ 51 | 52 | /* 53 | * tuple<...> の N番目要素の参照 : get() 54 | */ 55 | template 56 | Thead& get_tuple_data(tuple_data& t) 57 | { 58 | return t.value; 59 | } 60 | 61 | template 62 | auto get(tuple& t) -> decltype(get_tuple_data(t)) 63 | { 64 | return get_tuple_data(t); 65 | } 66 | 67 | int main() 68 | { 69 | tuple t; 70 | get<0>(t) = 'T'; 71 | get<1>(t) = 4; 72 | get<2>(t) = "two"; 73 | printType(get<0>(t), get<1>(t), get<2>(t)); 74 | } 75 | -------------------------------------------------------------------------------- /02_basic_template/23_initialize.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | 8 | template 9 | std::vector initializer() 10 | { 11 | std::vector v = { List... }; 12 | return v; 13 | } 14 | 15 | int main() 16 | { 17 | std::vector v = initializer<1, 2, 3>(); 18 | 19 | for (int x : v) { 20 | std::cout << x << std::endl; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /03_generic_programming/01_find.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | Iterator find(Iterator first, Iterator last, const T& value) 12 | { 13 | while (first != last) { 14 | if (*first == value) 15 | break; // 見つかった! 16 | 17 | ++first; 18 | } 19 | return first; 20 | } 21 | 22 | using namespace std; 23 | int main() 24 | { 25 | char arr[] = "hello"; 26 | vector v = {1, 2, 3}; 27 | list ls = {1L, 2L, 3L}; 28 | 29 | char* p = ::find(begin(arr), end(arr), 'e'); 30 | if (p != end(arr)) { /* 見つかった */ } 31 | 32 | decltype(v)::iterator itv = ::find(begin(v), end(v), 3); 33 | if (itv != end(v)) { /* 見つかった */ } 34 | 35 | decltype(ls)::iterator itls = ::find(begin(ls), end(ls), 3); 36 | if (itls != end(ls)) { /* 見つかった */ } 37 | } 38 | -------------------------------------------------------------------------------- /03_generic_programming/02_copy_01.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | template 10 | OutputIterator 11 | copy(InputIterator first, InputIterator last, OutputIterator out) 12 | { 13 | while (first != last) { 14 | *out = *first; 15 | ++out; 16 | ++first; 17 | } 18 | return out; 19 | } 20 | 21 | using namespace std; 22 | 23 | int main() 24 | { 25 | vector v = {1, 2, 3}; 26 | 27 | vector result; 28 | ::copy(begin(v), end(v), back_inserter(result)); 29 | 30 | for (int x : result) { 31 | cout << x << endl; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /03_generic_programming/02_copy_02.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | template 10 | OutputIterator 11 | copy(InputIterator first, InputIterator last, OutputIterator out) 12 | { 13 | while (first != last) { 14 | *out = *first; 15 | ++out; 16 | ++first; 17 | } 18 | return out; 19 | } 20 | 21 | using namespace std; 22 | 23 | int main() 24 | { 25 | vector v = {1, 2, 3}; 26 | 27 | vector result(v.size()); // 十分な領域を用意しておく 28 | ::copy(begin(v), end(v), begin(result)); 29 | 30 | for (int x : result) { 31 | cout << x << endl; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /03_generic_programming/03_find_if_01.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | template 10 | Iterator find_if(Iterator first, Iterator last, Predicate pred) 11 | { 12 | while (first != last) { 13 | if (pred(*first)) 14 | break; // 見つかった! 15 | 16 | ++first; 17 | } 18 | return first; 19 | } 20 | 21 | // 値が偶数か判定する関数オブジェクト 22 | struct is_even { 23 | bool operator()(int x) const 24 | { return x % 2 == 0; } 25 | }; 26 | 27 | using namespace std; 28 | 29 | int main() 30 | { 31 | vector v = {1, 2, 3}; 32 | 33 | decltype(v)::iterator it = ::find_if(begin(v), end(v), is_even()); 34 | if (it != end(v)) { // 見つかった 35 | cout << *it << endl; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /03_generic_programming/03_find_if_02.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | template 10 | Iterator find_if(Iterator first, Iterator last, Predicate pred) 11 | { 12 | while (first != last) { 13 | if (pred(*first)) 14 | break; // 見つかった! 15 | 16 | ++first; 17 | } 18 | return first; 19 | } 20 | 21 | using namespace std; 22 | 23 | int main() 24 | { 25 | vector v = {1, 2, 3}; 26 | 27 | decltype(v)::iterator it = ::find_if(begin(v), end(v), [](int x){ 28 | return x % 2 == 0; 29 | }); 30 | if (it != end(v)) { // 見つかった 31 | cout << *it << endl; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /03_generic_programming/04_selection_sort.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | void selection_sort(Iterator first, Iterator last) 7 | { 8 | for (Iterator p = first; p != last; ++p) { 9 | Iterator min_position = p; 10 | for (Iterator q = p; q != last; ++q) { 11 | if (*min_position > *q) { 12 | min_position = q; 13 | } 14 | } 15 | auto tmp = *min_position; 16 | *min_position = *p; 17 | *p = tmp; 18 | } 19 | } 20 | 21 | template 22 | void selection_sort(Iterator first, Iterator last, Compare comp) 23 | { 24 | for (Iterator p = first; p != last; ++p) { 25 | Iterator min_position = p; 26 | for (Iterator q = p; q != last; ++q) { 27 | if (comp(*q, *min_position)) { 28 | min_position = q; 29 | } 30 | } 31 | auto tmp = *min_position; 32 | *min_position = *p; 33 | *p = tmp; 34 | } 35 | } 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | int main() 42 | { 43 | int data[] = { 9, 7, 5, 3, 1, 8, 6, 4, 2, 0 }; 44 | 45 | selection_sort(std::begin(data), std::end(data), std::greater()); 46 | for (int x : data) { 47 | std::cout << x << ' '; 48 | } 49 | std::cout << std::endl; 50 | } 51 | -------------------------------------------------------------------------------- /03_generic_programming/05_print_all.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | void print_all(std::pair iter_pair) 12 | { 13 | while (iter_pair.first != iter_pair.second) { 14 | std::cout << *iter_pair.first << ' '; 15 | ++iter_pair.first; 16 | } 17 | std::cout << std::endl; 18 | } 19 | 20 | int main() 21 | { 22 | int ar[] = { 1, 2, 4, 8, 16 }; 23 | std::vector v(std::begin(ar), std::end(ar)); 24 | 25 | print_all(std::make_pair(std::begin(ar), std::end(ar))); 26 | print_all(std::make_pair(std::begin(v), std::end(v))); 27 | } 28 | -------------------------------------------------------------------------------- /03_generic_programming/06_back_inserter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | int data[] = { 1, 2, 3 }; 12 | std::vector v; 13 | 14 | std::copy(std::begin(data), std::end(data), std::back_inserter(v)); 15 | } 16 | -------------------------------------------------------------------------------- /03_generic_programming/07_advance.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | // InputIterator版: “ひとつ進む”を繰り返す(あと戻り不可) 13 | template 14 | void _advance(InputIterator& iter, Distance offset, 15 | input_iterator_tag) 16 | { 17 | for (; 0 < offset; --offset) 18 | ++iter; 19 | } 20 | 21 | // ForwardIterator版: “ひとつ進む”を繰り返す(あと戻り不可) 22 | template 23 | void _advance(ForwardIterator& iter, Distance offset, 24 | forward_iterator_tag) 25 | { 26 | for (; 0 < offset; --offset) 27 | ++iter; 28 | } 29 | 30 | // BidirectionalIterator版: “ひとつ進む/ 戻る”を繰り返す 31 | template 32 | void _advance(BidirectionalIterator& iter, Distance offset, 33 | bidirectional_iterator_tag) 34 | { 35 | if (offset > 0){ 36 | // offsetが正のとき、“ひとつ進む”を繰り返す 37 | for (; 0 < offset; --offset) 38 | ++iter; 39 | } 40 | else { 41 | // offsetが負のとき、“ひとつ戻る”を繰り返す 42 | for (; offset < 0; ++offset) 43 | --iter; 44 | } 45 | } 46 | 47 | // RandomAccessIterator版: operator+=で一気にジャンプ 48 | template 49 | void _advance(RandomAccessIterator& iter, Distance offset, 50 | random_access_iterator_tag) 51 | { 52 | iter += offset; 53 | } 54 | 55 | template 56 | void advance(Iterator& iter, Distance offset) 57 | { 58 | _advance(iter, offset, 59 | typename iterator_traits::iterator_category()); 60 | } 61 | 62 | int main() 63 | { 64 | vector vec = {1, 2, 3}; 65 | list lst = {1, 2, 3}; 66 | 67 | decltype(vec)::iterator vi = begin(vec); 68 | ::advance(vi, 2); // viを2進める 69 | 70 | decltype(lst)::iterator li = begin(lst); 71 | ::advance(li, 3); // liを3進める 72 | } 73 | -------------------------------------------------------------------------------- /03_generic_programming/08_decoration_01.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | class Plain { 11 | public: 12 | string convert(const string& str) const 13 | { return str; } 14 | }; 15 | 16 | template 17 | class Bold : public Base { 18 | public: 19 | string convert(const string& str) const 20 | { return "" + Base::convert(str) + ""; } 21 | }; 22 | 23 | template 24 | class Italic: public Base { 25 | public: 26 | string convert(const string& str) const 27 | { return "" + Base::convert(str) + ""; } 28 | }; 29 | 30 | int main() 31 | { 32 | Bold b; 33 | string s1 = b.convert("Hello"); // Hello 34 | 35 | Italic i; 36 | string s2 = i.convert("Hello"); // Hello 37 | 38 | Italic> ib; 39 | string s3 = ib.convert("Hello"); // Hello 40 | 41 | assert(s1 == "Hello"); 42 | assert(s2 == "Hello"); 43 | assert(s3 == "Hello"); 44 | } 45 | -------------------------------------------------------------------------------- /03_generic_programming/08_decoration_02.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | class Plain { 12 | public: 13 | virtual string convert(const string& str) const 14 | { return str; } 15 | }; 16 | 17 | template 18 | class Bold : public Base { 19 | public: 20 | using Base::Base; // コンストラクタを継承する(C++11) 21 | 22 | virtual string convert(const string& str) const 23 | { return "" + Base::convert(str) + ""; } 24 | }; 25 | 26 | template 27 | class Italic: public Base { 28 | public: 29 | using Base::Base; 30 | 31 | virtual string convert(const string& str) const 32 | { return "" + Base::convert(str) + ""; } 33 | }; 34 | 35 | template 36 | class Size : public Base { 37 | string size_; 38 | public: 39 | using Base::Base; 40 | 41 | Size(int s) { ostringstream strm; strm << s; size_ = strm.str(); } 42 | virtual string convert(const string& str) const 43 | { return "" + 44 | Base::convert(str) + ""; } 45 | }; 46 | 47 | int main() 48 | { 49 | Plain p; 50 | Bold<> b; 51 | Italic<> i; 52 | Size>> sbi(5); // 多重のパラメータ化継承 53 | Italic> si(3); 54 | 55 | Plain* converter[5] = { &p, &b, &i, &sbi, &si }; 56 | 57 | for (Plain* c : converter) { 58 | cout << c->convert("Hello, C++") << endl; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /03_generic_programming/09_print_on.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | class Plain { 12 | public: 13 | virtual string convert(const string& str) const 14 | { return str; } 15 | }; 16 | 17 | template 18 | class Bold : public Base { 19 | public: 20 | using Base::Base; // コンストラクタを継承する(C++11) 21 | 22 | virtual string convert(const string& str) const 23 | { return "" + Base::convert(str) + ""; } 24 | }; 25 | 26 | template 27 | class Italic: public Base { 28 | public: 29 | using Base::Base; 30 | 31 | virtual string convert(const string& str) const 32 | { return "" + Base::convert(str) + ""; } 33 | }; 34 | 35 | template 36 | class Size : public Base { 37 | string size_; 38 | public: 39 | using Base::Base; 40 | 41 | Size(int s) { ostringstream strm; strm << s; size_ = strm.str(); } 42 | virtual string convert(const string& str) const 43 | { return "" + 44 | Base::convert(str) + ""; } 45 | }; 46 | 47 | int main() 48 | { 49 | Plain p; 50 | Bold<> b; 51 | Italic<> i; 52 | Size>> sbi(5); // 多重のパラメータ化継承 53 | Italic> si(3); 54 | 55 | Plain* converter[5] = { &p, &b, &i, &sbi, &si }; 56 | 57 | for (Plain* c : converter) { 58 | cout << c->convert("Hello, C++") << endl; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /04_template_meta_programming/01_increment.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | struct increment { 7 | static const int value = N + 1; 8 | }; 9 | 10 | int main() 11 | { 12 | const int result = increment<3>::value; 13 | static_assert(result == 4, "result is 4"); 14 | } 15 | -------------------------------------------------------------------------------- /04_template_meta_programming/02_factorial.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | struct factorial { 7 | static const int value = N * factorial::value; 8 | }; 9 | 10 | template <> 11 | struct factorial<0> { 12 | static const int value = 1; 13 | }; 14 | 15 | int main() 16 | { 17 | const int result = factorial<3>::value; 18 | static_assert(result == 6, "result is 6"); 19 | } 20 | -------------------------------------------------------------------------------- /04_template_meta_programming/03_square.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | struct square { 7 | static const int value = N * N; 8 | }; 9 | 10 | int main() 11 | { 12 | const int result = square<3>::value; 13 | static_assert(result == 9, "result is 9"); 14 | } 15 | -------------------------------------------------------------------------------- /04_template_meta_programming/04_pow.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | struct pow { 7 | static const int value = X * pow::value; 8 | }; 9 | 10 | template 11 | struct pow { 12 | static const int value = 1; 13 | }; 14 | 15 | int main() 16 | { 17 | const int result = pow<2, 3>::value; 18 | static_assert(result == 8, "result is 8"); 19 | } 20 | -------------------------------------------------------------------------------- /04_template_meta_programming/05_identity.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template // パラメータで型Tを受け取って 6 | struct identity { 7 | typedef T type; // 型Tを返す 8 | }; 9 | 10 | int main() 11 | { 12 | identity::type value; 13 | } 14 | -------------------------------------------------------------------------------- /04_template_meta_programming/06_add_pointer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | struct add_pointer { 7 | typedef T* type; 8 | }; 9 | 10 | int main() 11 | { 12 | int value = 3; 13 | add_pointer::type p = &value; 14 | } 15 | -------------------------------------------------------------------------------- /04_template_meta_programming/07_add_lvalue_reference.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | struct add_const_lvalue_reference { 7 | typedef const T& type; 8 | }; 9 | 10 | int main() 11 | { 12 | int value = 3; 13 | add_const_lvalue_reference::type cr = value; 14 | } 15 | -------------------------------------------------------------------------------- /04_template_meta_programming/08_separate_meta_function.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | struct add_const { 7 | typedef const T type; 8 | }; 9 | 10 | template 11 | struct add_lvalue_reference { 12 | typedef T& type; 13 | }; 14 | 15 | template 16 | struct add_lvalue_reference { 17 | typedef T& type; 18 | }; 19 | 20 | int main() 21 | { 22 | int value = 3; 23 | add_const::type c = value; // c : const int 24 | add_lvalue_reference::type r = value; // r : int& 25 | } 26 | -------------------------------------------------------------------------------- /04_template_meta_programming/09_combine_meta_function.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | struct add_const { 7 | typedef const T type; 8 | }; 9 | 10 | template 11 | struct add_lvalue_reference { 12 | typedef T& type; 13 | }; 14 | 15 | template 16 | struct add_lvalue_reference { 17 | typedef T& type; 18 | }; 19 | 20 | template 21 | struct add_const_lvalue_reference { 22 | typedef 23 | typename add_const< 24 | typename add_lvalue_reference::type 25 | >::type 26 | type; 27 | }; 28 | 29 | int main() 30 | { 31 | int value = 3; 32 | add_const_lvalue_reference::type cr = value; // cr : const int& 33 | } 34 | -------------------------------------------------------------------------------- /04_template_meta_programming/10_remove_const.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | struct remove_const { 7 | typedef T type; 8 | }; 9 | 10 | template 11 | struct remove_const { 12 | typedef T type; 13 | }; 14 | 15 | int main() 16 | { 17 | remove_const::type value = 3; 18 | } 19 | -------------------------------------------------------------------------------- /04_template_meta_programming/11_remove_cv.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | struct remove_const { 7 | typedef T type; 8 | }; 9 | 10 | template 11 | struct remove_const { 12 | typedef T type; 13 | }; 14 | 15 | template 16 | struct remove_volatile { 17 | typedef T type; 18 | }; 19 | 20 | template 21 | struct remove_volatile { 22 | typedef T type; 23 | }; 24 | 25 | template 26 | struct remove_cv { 27 | typedef typename remove_volatile< 28 | typename remove_const::type 29 | >::type type; 30 | }; 31 | 32 | int main() 33 | { 34 | remove_cv::type value = 3; 35 | } 36 | -------------------------------------------------------------------------------- /04_template_meta_programming/12_if.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | struct if_; 7 | 8 | template 9 | struct if_ { 10 | typedef Then type; 11 | }; 12 | 13 | template 14 | struct if_ { 15 | typedef Else type; 16 | }; 17 | 18 | int main() 19 | { 20 | if_::type value1; 21 | if_::type value2; 22 | } 23 | -------------------------------------------------------------------------------- /04_template_meta_programming/13_high_order_if.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | template 6 | struct if_c; 7 | 8 | template 9 | struct if_c { 10 | typedef Then type; 11 | }; 12 | 13 | template 14 | struct if_c { 15 | typedef Else type; 16 | }; 17 | 18 | template 19 | struct if_ : public if_c {}; 20 | 21 | template 22 | struct is_even { 23 | static const bool value = N % 2 == 0; 24 | }; 25 | 26 | int main() 27 | { 28 | if_, int, long>::type value; 29 | // 偶数だったらint, 奇数だったらlong型 30 | } 31 | -------------------------------------------------------------------------------- /04_template_meta_programming/14_cpp11_meta_func_00.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | 8 | template 9 | T* add_pointer(T); 10 | 11 | int main() 12 | { 13 | typedef decltype(add_pointer(std::declval())) result; 14 | static_assert(std::is_same::value, ""); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /04_template_meta_programming/15_cpp11_meta_func_01.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | 7 | /* メタ関数適用 8 | template 9 | T* add_pointer(); 10 | 11 | int main() 12 | { 13 | typedef decltype(add_pointer()) result; 14 | static_assert(std::is_same::value, ""); 15 | } 16 | */ 17 | 18 | // 再帰テンプレート 19 | template 20 | struct add_pointer_t { 21 | typedef typename add_pointer_t::type type; 22 | }; 23 | 24 | template 25 | struct add_pointer_t { 26 | typedef T type; 27 | }; 28 | 29 | template 30 | typename add_pointer_t::type add_pointer(); 31 | 32 | int main() 33 | { 34 | typedef decltype(add_pointer()) result; 35 | static_assert(std::is_same::value, ""); 36 | } 37 | -------------------------------------------------------------------------------- /04_template_meta_programming/16_cpp11_meta_func_02.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | 8 | template 9 | struct int_ {}; 10 | 11 | template 12 | struct bool_ {}; 13 | 14 | struct cont {}; 15 | struct end {}; 16 | 17 | template 18 | auto is_end(bool_) 19 | -> typename std::conditional::type; 20 | 21 | // 再帰テンプレート 22 | template 23 | auto add_pointers_impl(T, int_, cont) 24 | -> decltype(add_pointers_impl( 25 | std::declval(), 26 | int_(), 27 | std::declval()) 29 | )>() 30 | )); 31 | 32 | template 33 | auto add_pointers_impl(T, int_, end) 34 | -> T; 35 | 36 | template 37 | auto add_pointers(T, int_) 38 | -> decltype(add_pointers_impl( 39 | std::declval(), 40 | int_(), 41 | std::declval()) 43 | )>())); 44 | 45 | int main() 46 | { 47 | typedef decltype( 48 | add_pointers(std::declval(), int_<3>()) 49 | ) result; 50 | static_assert(std::is_same::value, ""); 51 | } 52 | 53 | -------------------------------------------------------------------------------- /04_template_meta_programming/17_cpp11_meta_func_03.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | 8 | template 9 | struct int_ {}; 10 | 11 | // 再帰テンプレート 12 | template 0)>::type* = nullptr> 14 | auto add_pointer(T, int_) -> decltype(add_pointer(std::declval(), int_())); 15 | 16 | template ::type* = nullptr> 18 | auto add_pointer(T, int_) -> T; 19 | 20 | int main() 21 | { 22 | typedef decltype( 23 | add_pointer(std::declval(), int_<3>()) 24 | ) result; 25 | static_assert(std::is_same::value, ""); 26 | } 27 | -------------------------------------------------------------------------------- /04_template_meta_programming/18_type_list_00_head_tail.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | #include 7 | 8 | template 9 | struct g { 10 | typedef Head head; 11 | typedef std::tuple tail; 12 | }; 13 | 14 | template 15 | struct f { 16 | typedef typename g::head head; 17 | typedef typename g::tail tail; 18 | }; 19 | 20 | typedef f list; 21 | 22 | static_assert(std::is_same< 23 | list::head, 24 | int 25 | >::value, "head must be int"); 26 | 27 | static_assert(std::is_same< 28 | list::tail, 29 | std::tuple 30 | >::value, "tail must be tuple"); 31 | 32 | int main() {} 33 | 34 | -------------------------------------------------------------------------------- /04_template_meta_programming/19_type_list_01_any_of.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 2 | // Akira Takahashi, Fumiki Fukuda. 3 | // Released under the CC0 1.0 Universal license. 4 | 5 | #include 6 | 7 | template