Download presentation
Presentation is loading. Please wait.
Published byBryce Maxwell Modified over 9 years ago
1
Concepts in C++
2
Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation => complex, long, hard to understand error messages
3
Example... std::list intList; intList.push_back(42);... intList.push_back(5);... std::sort(intList.begin(), intList.end()); Compiled with gcc:
4
Error messages /usr/include/c++/4.1.3/bits/stl_algo.h: In function ‘void std::sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = std::_List_iterator ]’: templ.cpp:13: instantiated from here /usr/include/c++/4.1.3/bits/stl_algo.h:2713: error: no match for ‘operator-’ in ‘__last - __first’ /usr/include/c++/4.1.3/bits/stl_algo.h: In function ‘void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = std::_List_iterator ]’: /usr/include/c++/4.1.3/bits/stl_algo.h:2714: instantiated from ‘void std::sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = std::_List_iterator ]’ templ.cpp:13: instantiated from here
5
Cont. /usr/include/c++/4.1.3/bits/stl_algo.h:2360: error: no match for ‘operator+’ in ‘__first + 16’ /usr/include/c++/4.1.3/bits/stl_algo.h: In function ‘void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = std::_List_iterator ]’: /usr/include/c++/4.1.3/bits/stl_algo.h:2363: instantiated from ‘void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = std::_List_iterator ]’ /usr/include/c++/4.1.3/bits/stl_algo.h:2714: instantiated from ‘void std::sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = std::_List_iterator ]’ templ.cpp:13: instantiated from here /usr/include/c++/4.1.3/bits/stl_algo.h:2273: error: no match for ‘operator+’ in ‘__first + 1’
6
Cont 2. /usr/include/c++/4.1.3/bits/stl_algo.h:2363: instantiated from ‘void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = std::_List_iterator ]’ /usr/include/c++/4.1.3/bits/stl_algo.h:2714: instantiated from ‘void std::sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = std::_List_iterator ]’ templ.cpp:13: instantiated from here /usr/include/c++/4.1.3/bits/stl_algo.h:2279: error: no match for ‘operator+’ in ‘__i + 1’
7
And the reason is: …in the STL implementation? The fact: sort requires random access iterator but list has only forward iterator But only this line refers to that: templ.cpp:13: instantiated from here /usr/include/c++/4.1.3/bits/stl_algo.h:2273: error: no match for ‘operator+’ in ‘__first + 1’
8
C++0x Well-known problem in industrial application In other languages (java, Eiffel, ADA) there are constrained generics In C++0x, there will be concepts
9
The language components Concept: Names requirements against template arguments Concept_map: Semantic relationship between a type and a concept Requires The concrete requirement list agains template arguments of a class or function
10
Concept List of function signatures and associated types Like: LessThanComparable concept concept LessThanComparable { bool operator<(T a, T b); };
11
Requires LessThanComparable concept in a concrete template algorithm: template requires LessThanComparable T min(const T& a, const T& b) { return a < b ? a : b; };
12
Requires in other way: If a concept defines constraints on only one template parameter, there is a simpler way: template T min(const T& a, const T& b) { return a < b ? a : b; }; „Type”of a template
13
A bit more complex example concept Regular { // default constructor T:: T(); // copy constructor T:: T(const T&); // destructor T::˜T(); // copy assignment T& operator=(T&, const T&); // equality comparison bool operator==(const T&, const T&); // inequality comparison bool operator!=(const T&, const T&); // swap void swap(T&, T&); };
14
Multi-Type Concept Concepts may define requirements on more than one types: concept Convertible { operator U(const T&); }; And there is a way to express default parameters concept EqualtyComparable { bool operator==(T, U) };
15
Example of Multi-Type Concepts concept InputIterator { Iter :: Iter (); // default constructor Iter :: Iter (const Iter &); // copy constructor Iter ::˜ Iter (); // destructor Iter & operator=(Iter&, const Iter&); // copy assignment Value operator ∗ (const Iter&); // dereference Iter & operator++(Iter&); // pre- increment Iter operator++(Iter&, int); // post- increment bool operator==(const Iter&, const Iter&); // equality comparison bool operator!=(const Iter&, const Iter &); // inequality comparison void swap(Iter &, Iter &); // swap };
16
Concepts: composition „Regular” concept used for InputIterator concept: concept InputIterator { requires Regular ; Value operator ∗ (const Iter&); // dereference Iter& operator++(Iter&); // pre-increment Iter operator++(Iter&, int); // post-increment };
17
Concepts: refinement concept InputIterator : Regular { Value operator ∗ (const Iter&); // dereference Iter& operator++(Iter&); // pre-increment Iter operator++(Iter&, int); // post-increment }; Hint: if hierarchy, then refinement, Difference: in concept_map definition
18
A template using InputIterator concept template requires InputIterator void print(Iter first, Iter last) { while (first != last) { std::cout << *first++; } std::cout << std::endl; }
19
The real InputIterator concept concept InputIterator <typename Iter, typename Value, typename Reference typename Pointer, typename Di ff erence> { requires Regular ; requires Convertible ; Reference operator ∗ (const Iter&); // dereference Iter& operator++(Iter&); // pre-increment Iter operator++(Iter&, int); // post-increment //... }
20
The real template function using InputIterator template<typename Iter, Regular V, typename R, typename P, typename D> requires InputIterator void print(Iter first, Iter last) { while (first != last) { std::cout << *first++; } std::cout << std::endl; }
21
Associated Types Associated types: concept InputIterator { typename value type; typename reference; typename pointer; typename di ff erence type; requires Regular ; requires Convertible ; reference operator ∗ (const Iter&); Iter& operator++(Iter&); Iter operator++(Iter&, int); //... };
22
Template using InputIterator Now we have only one template parameter: template requires Regular void print(Iter first, Iter last) { while (first != last) { std::cout << *first++; } std::cout << std::endl; }
23
Concept_map Semantic relationship between a type and a concept: Example: looking for the best student: struct Student { std:string name; double avg; };... std::list l;... std::cout << (*std::min_element(l.begin(), l.end())).name << std::endl;
24
Concept_map 2 But operator< is not defined on Student Non-intrusive solution using concept_map: concept_map LessThanComparable { bool operator<(Diak a, Diak b) { return a.atlag < b.atlag; } };
25
Concept_map 3 If operator< is defined on some type X, we don’t need to redefine: concept_map LessThanComparable {} auto keyword: no concept_map is required
26
Other examples for Concept_map Suppose InputIterator is auto Then this partial concept_map definition is valid concept map InputIterator { typedef char value type ; typedef char& reference ; typedef char ∗ pointer ; typedef std::ptrdi ff _t di ff erence type ; }; The rest is generated automaticaly
27
More Concept_map If implicite (auto) declaration is not valid, e.c.: we want to define to use int-s, az iterator: concept map InputIterator { typedef int value type; typedef int reference; typedef int ∗ pointer; typedef int difference type; int operator ∗ (int x) { return x; } }; Thus, we could inialitize containers. std::copy(1, 101, v.begin());
28
Concept_map template concepts and concept_maps can be tempatized All the pointers are iterators template concept_map InputIterator { typedef T value type ; typedef T& reference ; typedef T ∗ pointer ; typedef std:: ptrdi ff t di ff erence type ; };
29
A container adaptor With concept, concept_map container adaptors could be defined without wrapper classes. concept Stack { typename value type; void push(X&, const value type&); void pop(X&); value type top(const X&); bool empty(const X&); };
30
And it’s concept_map template concept_map Stack > { typedef T value type; void push(std::vector & v, const T& x){ v.push_back(x); } void pop(std:: vector & v){ v.pop_back(); } T top(const std::vector & v){ return v.back(); } bool empty(const std::vector & v){ return v.empty(); } };
31
Concept-based Overloading Best matching template will be instantiated, Better way to implement many STl functions.
32
The advance fv. declarations template void advance(Iter& x, Iter::difference_type n) { while (n > 0) { ++x; --n; } } template void advance(Iter& x, Iter::difference_type n) { if (n > 0) while (n > 0) { ++x; --n; } else while (n < 0) { --x; ++n; } } template void advance(Iter& x, Iter::difference_type n) { x += n; }
33
Negative constraint template class dictionary { // slow, linked-list implementation }; template requires !Hashable class dictionary { // balanced binary tree implementation }; template class dictionary { // hash table implementation };
34
The error messages For the first example:... std::list intList; intList.push_back(42);... intList.push_back(5);... std::sort(intList.begin(), intList.end()); We got this compiler error: l istconc.cpp: In function ‘int main()’: listconc.cpp:9: error: no matching function for call to ‘sort(std::_List_iterator, std::_List_iterator )’ /home/lupin/local/conceptgcc/bin/../lib/gcc/i686-pc-linux- gnu/4.3.0/../../../../include/c++/4.3.0/bits/stl_algo.h:2874: note: candidates are: void std::sort(_Iter, _Iter) [with _Iter = std::_List_iterator ] listconc.cpp:9: note: no concept map for requirement ‘std::MutableRandomAccessIterator >’
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.