$30 off During Our Annual Pro Sale. View Details »

Lecture №2.3. Concepts

Baramiya Denis
September 16, 2022

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 г.

    View Slide

  2. View Slide

  3. TEMPLATES
    Unconstrained Constrained

    View Slide

  4. TEMPLATES
    Unconstrained Constrained

    View Slide

  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.

    View Slide

  6. SFINAE DISADVANTAGES
    1. Hard to implement.
    2. Template errors.
    3. Readability
    .

    4. Nested templates usually won’t work in
    enable_if statements.

    View Slide

  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

    ...

    View Slide

  8. CONCEPT DEFINITION
    $PODFQUEF
    fi
    OJUJPOJTBUFNQMBUFGPSBOBNFETFUPGDPOTUSBJOUT
    template
    concept name = constraints;
    w $PODFQUTBSFOFWFSJOTUBOUJBUFECZUIFDPNQJMFS
    w 5IFDPNQJMFSFWBMVBUFTBUDPNQJMFUJNF
    w 1BSBNFUFSMJTUDBODPOUBJOOPOUZQFQBSBNFUFST
    $POTUSBJOUTBSFMPHJDBMFYQSFTTJPOTUIBUDPOTJTUPGDPOKVODUJPOT

    BOEPSEJTKVODUJPOT cc
    PGDPOTUBOUCPPMFYQSFTTJPOT

    View Slide

  9. CONCEPT EXPRESSION
    template
    concept Small = sizeof(T) <= sizeof(int)
    ;

    Small or Small - concept expressions

    View Slide

  10. REQUIRES EXPRESSIONS
    template
    concept RandomAccessIterator = BidirectionalIterator>

    && /* Additional syntactical requirements for random-access
    iterators... */;

    View Slide

  11. REQUIRES EXPRESSIONS
    template
    concept RandomAccessIterator = BidirectionalIterator>

    && /* Additional syntactical requirements for random-access
    iterators... */;
    requires { requirements
    }

    requires (parameter list) { requirements }
    UZQFEWBSJBCMFT FYQSFTTJPOTXJUI
    EFDMBSFEWBSJBCMFT

    View Slide

  12. REQUIREMENT TYPES
    1. Simple requirements.
    2. Compound requirements.
    3. Type requirements
    .

    4. Nested requirements.

    View Slide

  13. SIMPLE REQUIREMENTS
    template
    concept RandomAccessIterator = BidirectionalIterator>

    && 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

    View Slide

  14. SIMPLE REQUIREMENTS
    template
    concept RandomAccessIterator = BidirectionalIterator>

    && 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?

    View Slide

  15. SIMPLE REQUIREMENTS
    template
    concept RandomAccessIterator = BidirectionalIterator>

    && 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
    ;

    }

    View Slide

  16. COMPOUND REQUIREMENTS
    { expr };
    { expr } noexcept
    ;

    { expr } -> type-constraint
    ;

    { expr } noexcept -> type-constraint;

    View Slide

  17. COMPOUND REQUIREMENTS
    { expr };
    { expr } noexcept
    ;

    { expr } -> type-constraint
    ;

    { expr } noexcept -> type-constraint;
    template
    concept NoExceptDestructible = requires (T& value
    )

    {

    { value.~T() } noexcept
    ;

    }

    View Slide

  18. COMPOUND REQUIREMENTS
    { expr };
    { expr } noexcept
    ;

    { expr } -> type-constraint
    ;

    { expr } noexcept -> type-constraint;
    template
    concept RandomAccessIterator = BidirectionalIterator>

    && requires (const Iter i, const Iter j, Iter k, const int n
    )

    {

    { i - n } -> std::same_as
    ;

    { i + n } -> std::same_as
    ;

    { k += n } -> std::same_as
    ;

    { i[n] } -> std::same_as
    ;

    { i < j } -> std::convertible_to
    ;

    ..
    .

    }

    View Slide

  19. COMPOUND REQUIREMENTS
    { expr };
    { expr } noexcept
    ;

    { expr } -> type-constraint
    ;

    { expr } noexcept -> type-constraint;
    template
    concept RandomAccessIterator = BidirectionalIterator>

    && requires (const Iter i, const Iter j, Iter k, const int n
    )

    {

    { i - n } -> std::same_as
    ;

    { i + n } -> std::same_as
    ;

    { k += n } -> std::same_as
    ;

    { i[n] } -> std::same_as
    ;

    { i < j } -> std::convertible_to
    ;

    ..
    .

    }

    View Slide

  20. COMPOUND REQUIREMENTS
    { expr };
    { expr } noexcept
    ;

    { expr } -> type-constraint
    ;

    { expr } noexcept -> type-constraint;
    template
    concept RandomAccessIterator = BidirectionalIterator>

    && requires (const Iter i, const Iter j, Iter k, const int n
    )

    {

    { i - n } -> std::same_as
    ;

    { i + n } -> std::same_as
    ;

    { k += n } -> std::same_as
    ;

    { i[n] } -> std::same_as
    ;

    { i < j } -> std::convertible_to
    ;

    ..
    .

    }
    { expr } -> concept; => concept

    View Slide

  21. COMPOUND REQUIREMENTS
    { expr };
    { expr } noexcept
    ;

    { expr } -> type-constraint
    ;

    { expr } noexcept -> type-constraint;
    template
    concept RandomAccessIterator = BidirectionalIterator>

    && requires (const Iter i, const Iter j, Iter k, const int n
    )

    {

    { i - n } -> Iter; /*Error: Iter is a type, not a type constraint*/
    ..
    .

    }

    View Slide

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

    View Slide

  23. TYPE & NESTED REQUIREMENTS
    typename name; // name is a valid type name
    requires constraints; // same as in
    /
    /
    'template concept = constraints;'
    template
    concept String = requires (S& s, const S& cs
    )

    {

    typename S::value_type
    ;

    requires Character; // ~ predicate
    s

    { cs.length() } -> std::integral;
    ...
    }

    View Slide

  24. REQUIRES EXPR IN REQUIRES EXPR
    template
    concept String = requires (S& s, const S& cs
    )

    {

    typename S::value_type
    ;

    requires requires (typename S::value_type x) { ++x; }
    ...
    }

    View Slide

  25. REQUIRES CLAUSE
    //By requires claus
    e

    template >

    requires Sortable
    void sort(Container& container)
    ;

    //By requires clause
    template
    void sort(Container& container) requires Sortable
    ;

    //By concept
    template
    void sort(Container& container);
    CPPMFYQSFTTJPOT
    XJUIcc

    View Slide

  26. REQUIRES CLAUSE
    template >

    requires !is_trivial_v
    void function(T param)
    ;

    Not compiled

    View Slide

  27. REQUIRES CLAUSE
    template >

    requires (!is_trivial_v
    )

    void function(T param)
    ;

    Compiled

    View Slide

  28. SPECIALIZATION
    template >

    requires is_trivial_v
    void function(T param)
    ;

    template >

    void function(T param)
    ;

    View Slide

  29. CONJUNCTION AND DISJUNCTION
    template >

    requires is_trivial_v>

    || is_trivial_v
    void function(T param)
    ;

    template >

    requires (is_trivial_v>

    || is_trivial_v
    )

    void function(T param);

    View Slide

  30. КОНЕЦ ТРЕТЬЕЙ ЛЕКЦИИ

    View Slide