Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Lecture №2.3. Concepts

Lecture №2.3. Concepts

1. Constrained and unconstrained templates.
2. SFINAE disadvantages.
3. Requirement types.
4. Concept definitions and expressions.
5. Requires expressions.
6. Requires clause.
7. Specialization.

Baramiya Denis

September 16, 2022
Tweet

More Decks by Baramiya Denis

Other Decks in Programming

Transcript

  1. ОБЪЕКТНО- ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ Лекция № 2 / 3 
 16.09.2022

    г.
  2. None
  3. TEMPLATES Unconstrained Constrained

  4. TEMPLATES Unconstrained Constrained

  5. TEMPLATES Unconstrained Constrained • The signature specifies the template argument

    constraints. • Template arguments type checking. • A template is only instantiated if the template arguments satisfy all constraints. • Error messages closer to the root cause of the problem.
  6. SFINAE DISADVANTAGES 1. Hard to implement. 2. Template errors. 3.

    Readability . 4. Nested templates usually won’t work in enable_if statements.
  7. CONCEPTS - A NAMED SET OF REQUIREMENTS Syntactic Semantic Complexity

    i + n ; i += n; Compile d i[n] ; ... *(i + n) ~ i[n] i += -n ~ i -= n i += n ~ ++i (n times ) ... i - random-access iterator; n - integral value; i += n i + n O(1) complexity i -= n ...
  8. CONCEPT DEFINITION $PODFQUEF fi OJUJPOJTBUFNQMBUFGPSBOBNFETFUPGDPOTUSBJOUT template <parameter list> concept name

    = constraints; w $PODFQUTBSFOFWFSJOTUBOUJBUFECZUIFDPNQJMFS w 5IFDPNQJMFSFWBMVBUFTBUDPNQJMFUJNF w 1BSBNFUFSMJTUDBODPOUBJOOPOUZQFQBSBNFUFST $POTUSBJOUTBSFMPHJDBMFYQSFTTJPOTUIBUDPOTJTUPGDPOKVODUJPOT  BOEPSEJTKVODUJPOT cc PGDPOTUBOUCPPMFYQSFTTJPOT
  9. CONCEPT EXPRESSION template <typename T> concept Small = sizeof(T) <=

    sizeof(int) ; Small<char> or Small<double> - concept expressions
  10. REQUIRES EXPRESSIONS template <typename Iter> concept RandomAccessIterator = BidirectionalIterator<Iter >

    && /* Additional syntactical requirements for random-access iterators... */;
  11. REQUIRES EXPRESSIONS template <typename Iter> concept RandomAccessIterator = BidirectionalIterator<Iter >

    && /* Additional syntactical requirements for random-access iterators... */; requires { requirements } requires (parameter list) { requirements } UZQFEWBSJBCMFT FYQSFTTJPOTXJUI EFDMBSFEWBSJBCMFT
  12. REQUIREMENT TYPES 1. Simple requirements. 2. Compound requirements. 3. Type

    requirements . 4. Nested requirements.
  13. SIMPLE REQUIREMENTS template <typename Iter> concept RandomAccessIterator = BidirectionalIterator<Iter >

    && requires (Iter i, Iter j, int n ) { /* int v; Error: not an expression statement */ i + n; i - n; n + i; i += n; i -= n; i[n] ; i < j; i > j; i <= j; i >= j ; } (MPCBMWBSJBCMFTPSWBSJBCMFT JOUSPEVDFEJOUIFQBSBNFUFSMJTU
  14. SIMPLE REQUIREMENTS template <typename Iter> concept RandomAccessIterator = BidirectionalIterator<Iter >

    && requires (Iter i, Iter j, int n ) { /* int v; Error: not an expression statement */ i + n; i - n; n + i; i += n; i -= n; i[n] ; i < j; i > j; i <= j; i >= j ; } (MPCBMWBSJBCMFTPSWBSJBCMFT JOUSPEVDFEJOUIFQBSBNFUFSMJTU Disadvantages?
  15. SIMPLE REQUIREMENTS template <typename Iter> concept RandomAccessIterator = BidirectionalIterator<Iter >

    && requires (const Iter i, const Iter j, Iter k, const int n ) { i + n; i - n; n + i; i[n] ; k += n; k -= n ; i < j; i > j; i <= j; i >= j ; }
  16. COMPOUND REQUIREMENTS { expr }; { expr } noexcept ;

    { expr } -> type-constraint ; { expr } noexcept -> type-constraint;
  17. COMPOUND REQUIREMENTS { expr }; { expr } noexcept ;

    { expr } -> type-constraint ; { expr } noexcept -> type-constraint; template <typename Iter> concept NoExceptDestructible = requires (T& value ) { { value.~T() } noexcept ; }
  18. COMPOUND REQUIREMENTS { expr }; { expr } noexcept ;

    { expr } -> type-constraint ; { expr } noexcept -> type-constraint; template <typename Iter> concept RandomAccessIterator = BidirectionalIterator<Iter > && requires (const Iter i, const Iter j, Iter k, const int n ) { { i - n } -> std::same_as<Iter> ; { i + n } -> std::same_as<Iter> ; { k += n } -> std::same_as<Iter&> ; { i[n] } -> std::same_as<decltype(*i)> ; { i < j } -> std::convertible_to<bool> ; .. . }
  19. COMPOUND REQUIREMENTS { expr }; { expr } noexcept ;

    { expr } -> type-constraint ; { expr } noexcept -> type-constraint; template <typename Iter> concept RandomAccessIterator = BidirectionalIterator<Iter > && requires (const Iter i, const Iter j, Iter k, const int n ) { { i - n } -> std::same_as<Iter> ; { i + n } -> std::same_as<Iter> ; { k += n } -> std::same_as<Iter&> ; { i[n] } -> std::same_as<decltype(*i)> ; { i < j } -> std::convertible_to<bool> ; .. . }
  20. COMPOUND REQUIREMENTS { expr }; { expr } noexcept ;

    { expr } -> type-constraint ; { expr } noexcept -> type-constraint; template <typename Iter> concept RandomAccessIterator = BidirectionalIterator<Iter > && requires (const Iter i, const Iter j, Iter k, const int n ) { { i - n } -> std::same_as<Iter> ; { i + n } -> std::same_as<Iter> ; { k += n } -> std::same_as<Iter&> ; { i[n] } -> std::same_as<decltype(*i)> ; { i < j } -> std::convertible_to<bool> ; .. . } { expr } -> concept<Args...>; => concept<decltype(expr), Args...>
  21. COMPOUND REQUIREMENTS { expr }; { expr } noexcept ;

    { expr } -> type-constraint ; { expr } noexcept -> type-constraint; template <typename Iter> concept RandomAccessIterator = BidirectionalIterator<Iter > && requires (const Iter i, const Iter j, Iter k, const int n ) { { i - n } -> Iter; /*Error: Iter is a type, not a type constraint*/ .. . }
  22. TYPE & NESTED REQUIREMENTS typename name; // name is a

    valid type name requires constraints; // same as in / / 'template <params> concept = constraints;'
  23. TYPE & NESTED REQUIREMENTS typename name; // name is a

    valid type name requires constraints; // same as in / / 'template <params> concept = constraints;' template <typename S> concept String = requires (S& s, const S& cs ) { typename S::value_type ; requires Character<typename S::value_type>; // ~ predicate s { cs.length() } -> std::integral; ... }
  24. REQUIRES EXPR IN REQUIRES EXPR template <typename S> concept String

    = requires (S& s, const S& cs ) { typename S::value_type ; requires requires (typename S::value_type x) { ++x; } ... }
  25. REQUIRES CLAUSE //By requires claus e template <typename Container >

    requires Sortable<Container> void sort(Container& container) ; //By requires clause template <typename Container> void sort(Container& container) requires Sortable<Container> ; //By concept template <Sortable Container> void sort(Container& container); CPPMFYQSFTTJPOT XJUIcc
  26. REQUIRES CLAUSE template <typename T > requires !is_trivial_v<T> void function(T

    param) ; Not compiled
  27. REQUIRES CLAUSE template <typename T > requires (!is_trivial_v<T> ) void

    function(T param) ; Compiled
  28. SPECIALIZATION template <typename T > requires is_trivial_v<typename T::value_type> void function(T

    param) ; template <typename T > void function(T param) ;
  29. CONJUNCTION AND DISJUNCTION template <typename T, typename U > requires

    is_trivial_v<typename T::value_type > || is_trivial_v<typename U::value_type> void function(T param) ; template <typename T, typename U > requires (is_trivial_v<typename T::value_type > || is_trivial_v<typename U::value_type> ) void function(T param);
  30. КОНЕЦ ТРЕТЬЕЙ ЛЕКЦИИ