34
Concepts in C++

Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Embed Size (px)

Citation preview

Page 1: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Concepts in C++

Page 2: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

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

Page 3: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Example

...

std::list<int> intList;

intList.push_back(42); ... intList.push_back(5);

...

std::sort(intList.begin(), intList.end());

Compiled with gcc:

Page 4: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Error messages

/usr/include/c++/4.1.3/bits/stl_algo.h: In function ‘void

std::sort(_RandomAccessIterator, _RandomAccessIterator) [with

_RandomAccessIterator = std::_List_iterator<int>]’:

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<int>]’:

/usr/include/c++/4.1.3/bits/stl_algo.h:2714: instantiated from ‘void

std::sort(_RandomAccessIterator, _RandomAccessIterator) [with

_RandomAccessIterator = std::_List_iterator<int>]’

templ.cpp:13: instantiated from here

Page 5: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

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<int>]’:

/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<int>]’

/usr/include/c++/4.1.3/bits/stl_algo.h:2714: instantiated from ‘void

std::sort(_RandomAccessIterator, _RandomAccessIterator) [with

_RandomAccessIterator = std::_List_iterator<int>]’

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’

Page 6: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

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<int>]’

/usr/include/c++/4.1.3/bits/stl_algo.h:2714: instantiated from ‘void

std::sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = std::_List_iterator<int>]’

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’

Page 7: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

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’

Page 8: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

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

Page 9: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

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

Page 10: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Concept

List of function signatures and associated types Like: LessThanComparable concept

concept LessThanComparable<typename T> { bool operator<(T a, T b); };

Page 11: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Requires

LessThanComparable concept in a concrete

template algorithm:template<typename T>requires LessThanComparable<T>T min(const T& a, const T& b){ return a < b ? a : b;};

Page 12: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Requires in other way:

If a concept defines constraints on only one

template parameter, there is a simpler way: template<LessThanComparable T> T min(const T& a, const T& b) { return a < b ? a : b; };

„Type”of a template

Page 13: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

A bit more complex exampleconcept Regular<typename T> { // 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&); };

Page 14: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Multi-Type Concept

Concepts may define requirements on more than

one types: concept Convertible<typename T, typename U> { operator U(const T&); };

And there is a way to express default parameters concept EqualtyComparable<typename T, typename U = T>

{ bool operator==(T, U) };

Page 15: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Example of Multi-Type Concepts

concept InputIterator <typename Iter, typename Value> {

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

};

Page 16: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Concepts: composition

„Regular” concept used for InputIterator concept:

concept InputIterator<typename Iter, typename Value>

{ requires Regular<Iter>;

Value operator∗(const Iter&); // dereference Iter& operator++(Iter&); // pre-increment Iter operator++(Iter&, int); // post-increment};

Page 17: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Concepts: refinement

concept InputIterator<typename Iter,typename Value> : Regular<Value>

{ 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

Page 18: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

A template using InputIterator concept

template<typename Iter, Regular V>requires InputIterator<Iter, V>

void print(Iter first, Iter last){ while (first != last) { std::cout << *first++;}

std::cout << std::endl;}

Page 19: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

The real InputIterator concept

concept InputIterator<typename Iter, typename Value, typename Reference typename Pointer, typename

Di erence>ff{ requires Regular<Iter>; requires Convertible<Reference, Value>; Reference operator∗(const Iter&); // dereference Iter& operator++(Iter&); // pre-increment Iter operator++(Iter&, int); // post-increment // ...}

Page 20: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

The real template function using

InputIterator

template<typename Iter, Regular V, typename R, typename P, typename D>requires InputIterator<Iter, V, R, P, D>

void print(Iter first, Iter last){ while (first != last) { std::cout << *first++;}

std::cout << std::endl;}

Page 21: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Associated Types

Associated types:concept InputIterator<typename Iter> { typename value type; typename reference; typename pointer; typename di erence type;ff requires Regular<Iter>; requires Convertible<reference type, value type>; reference operator∗(const Iter&); Iter& operator++(Iter&); Iter operator++(Iter&, int); // ...};

Page 22: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Template using InputIterator

Now we have only one template parameter:template<InputIterator Iter>requires Regular<Iter::value type>void print(Iter first, Iter last){ while (first != last) { std::cout << *first++;}

std::cout << std::endl;}

Page 23: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

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<Student> l; ... std::cout << (*std::min_element(l.begin(), l.end())).name << std::endl;

Page 24: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Concept_map 2

But operator< is not defined on Student Non-intrusive solution using concept_map: concept_map LessThanComparable<Diak> { bool operator<(Diak a, Diak b) { return a.atlag < b.atlag; } };

Page 25: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Concept_map 3

If operator< is defined on some type X, we don’t

need to redefine: concept_map LessThanComparable<X>{}

auto keyword: no concept_map is required

Page 26: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Other examples for Concept_map

Suppose InputIterator is auto Then this partial concept_map definition is valid concept map InputIterator<char∗> { typedef char value type ; typedef char& reference ; typedef char∗ pointer ; typedef std::ptrdi _t di erence type ;ff ff };

The rest is generated automaticaly

Page 27: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

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<int> { 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());

Page 28: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Concept_map template

concepts and concept_maps can be tempatized All the pointers are iterators

template<typename T> concept_map InputIterator<T*> { typedef T value type ; typedef T& reference ; typedef T∗ pointer ; typedef std:: ptrdi t di erence type ;ff ff };

Page 29: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

A container adaptor

With concept, concept_map container adaptors

could be defined without wrapper classes. concept Stack<typename X> { typename value type; void push(X&, const value type&); void pop(X&); value type top(const X&); bool empty(const X&); };

Page 30: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

And it’s concept_maptemplate<typename T>concept_map Stack<std::vector<T> >{ typedef T value type; void push(std::vector<T>& v, const T& x){ v.push_back(x); } void pop(std:: vector <T>& v){ v.pop_back(); } T top(const std::vector <T>& v){ return v.back(); } bool empty(const std::vector <T>& v){ return v.empty(); }};

Page 31: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Concept-based Overloading Best matching template will be instantiated, Better way to implement many STl functions.

Page 32: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

The advance fv. declarations

template<InputIterator Iter>void advance(Iter& x, Iter::difference_type n) { while (n > 0) { ++x; --n; }}

template<BidirectionalIterator Iter>void advance(Iter& x, Iter::difference_type n) { if (n > 0) while (n > 0) { ++x; --n; } else while (n < 0) { --x; ++n; }}

template<RandomAccessIterator Iter>void advance(Iter& x, Iter::difference_type n) { x += n;}

Page 33: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

Negative constraint

template<EqualityComparable T>class dictionary { // slow, linked-list implementation};

template<LessThanComparable T>requires !Hashable<T>class dictionary<T> { // balanced binary tree implementation};

template<Hashable T>class dictionary<T> { // hash table implementation};

Page 34: Concepts in C++. Templates in current C++ C++ template is typeless No language support for constrained generics Accidental errors found in instantiation

The error messages

For the first example:...std::list<int> intList;intList.push_back(42); ... intList.push_back(5);...std::sort(intList.begin(), intList.end());

We got this compiler error:

listconc.cpp: In function ‘int main()’:listconc.cpp:9: error: no matching function for call to

‘sort(std::_List_iterator<int>, std::_List_iterator<int>)’/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<int>] <where clause>

listconc.cpp:9: note: no concept map for requirement ‘std::MutableRandomAccessIterator<std::_List_iterator<int> >’