[ Web Proxy ]
URL:
Viewing: https://ru.cppreference.com/cpp/experimental/constraints [Back]  [Original]

cppreference.com
cppreference.com

cppreference.com
 
C++
(C++20)
(C++20)
(C++11)
(C++20)
/
(C++11)
(C++11)
(C++11)
(C++17)
 
( )
( )
2 ( v2)
3 ( v3)
( )
2 ( v2)
2 ( v2)
( )
( )
( )
( )
 


. , ,

, ( ) , , .

, .

. , , :

#include <string>
#include <locale>
using namespace std::literals;

//   "EqualityComparable",  
//   T, ,    a  b  T,
//  a==b ,        bool
template<typename T>
concept bool EqualityComparable = requires(T a, T b) {
    { a == b } -> bool;
};

void f(EqualityComparable&&); //    
// template<typename T>
// void f(T&&) requires EqualityComparable<T>; //    

int main() {
  f("abc"s); // OK, std::string  EqualityComparable
  f(std::use_facet<std::ctype<char>>(std::locale{})); // :  EqualityComparable 
}

, , .

std::list<int> l = {3,-1,10};
std::sort(l.begin(), l.end()); 
//    :
//  invalid operands to binary expression ('std::_List_iterator<int>' and
//  'std::_List_iterator<int>')
//                           std::__lg(__last - __first) * 2);
//                                     ~~~~~~ ^ ~~~~~~~
// ... 50   ...
//
//    :
//  error: cannot call std::sort with std::_List_iterator<int>
//  note:  concept RandomAccessIterator<std::_List_iterator<int>> was not satisfied

(Number, Range, RegularFunction), (HasPlus, Array). ISO C++ T.20, " , ."

, __cpp_concepts , 201507.

auto , - < --(optional)>, .

( ) ( )

std::pair<auto, auto> p2 = std::make_pair(0, 'a'); //  auto  int,
                                                   //  auto  char

Sortable x = f(y); //  x     f,  
                   //   ,     Sortable

auto f(Container) -> Sortable; //    
                               //   return,  
                               //   ,    Sortable

, (, )

void f(std::pair<auto, EqualityComparable>); //     :
       //        

, auto, , -.

auto gl = [](Assignable& a, auto* b) { a = *b; };

, , :

template<size_t N> concept bool Even = (N%2 == 0);
struct S1 { int n; };
int Even::* p2 = &S1::n; // ,   ,
                         //    
void f(std::array<auto, Even>); // ,   ,
                                //    
template<Even N> void f(std::array<auto, N>); // OK

, , .

//  :
void g1(const EqualityComparable*, Incrementable&);
//  :
// template<EqualityComparable T, Incrementable U> void g1(const T*, U&);
//   :
// template<typename T, typename U>
// void g1(const T*, U&) requires EqualityComparable<T> && Incrementable<U>;

void f2(std::vector<auto*>...);
//  : template<typename... T> void f2(std::vector<T*>...);

void f4(auto (auto::*)(auto));
//  : template<typename T, typename U, typename V> void f4(T (U::*)(V));

, , . (auto) .

void f0(Comparable a, Comparable* b);
//  : template<Comparable T> void f0(T a, T* b);

void f1(auto a, auto* b);
//  : template<typename T, typename U> f1(T a, U* b);

, , - { -()} , template : - , (, , ) .

, ( ), ( ) ( ) , .

EqualityComparable{T} class Foo;
//  : template<EqualityComparable T> class Foo;
//   : template<typename T> requires EqualityComparable<T> class Foo;

template<typename T, int N, typename... Xs> concept bool Example = ...;
Example{A, B, ...C} struct S1;
//  
// template<class A, int B, class... C> requires Example<A,B,C...> struct S1;

:

Sortable{T} void f(T, auto);
//  : template<Sortable T, typename U> void f(T, U);
//     : void f(Sortable, auto);

. ( ) ( ). , concept --:

//      ( )
template <class T, class U>
concept bool Derived = std::is_base_of<U, T>::value;

//      ( )
template <class T>
concept bool EqualityComparable() { 
    return requires(T a, T b) { {a == b} -> Boolean; {a != b} -> Boolean; };
}

:

  • inline constexpr , inline constexpr
  • friend virtual
  • , noexcept(true).
  • ,
  • bool
  • return, - ( , / -requires, )

:

  • bool
  • .
  • constexpr , constexpr
  • ( , / -requires, )

:

template<typename T>
concept bool F() { return F<typename T::type>(); } // 
template<typename T>
concept bool V = V<T*>; // 

, ( )

, . -requires ( )

9 :

1)
2)
3)
4) ( -requires)
5) ( -requires)
6) ( -requires)
7) ( -requires)
8) ( -requires)
9) ( -requires)

-requires

template<typename T>
requires // -requires ( )
sizeof(T) > 1 && get_value<T>() //    
void f(T);

, : , , , requires , , requires:

//          
//   Incrementable<T> && Decrementable<T>
template<Incrementable T> void f(T) requires Decrementable<T>;
template<typename T> requires Incrementable<T> && Decrementable<T> void f(T); // ok

//      :
//    Incrementable<T> && Decrementable<T>
//    Decrementable<T> && Incrementable<T>
//    .
//    ,   

template<Incrementable T> requires Decrementable<T> void g();
template<Decrementable T> requires Incrementable<T> void g(); // 

P Q P && Q.

//      ( )
template <class T>
concept bool Integral = std::is_integral<T>::value;
template <class T>
concept bool SignedIntegral = Integral<T> && std::is_signed<T>::value;
template <class T>
concept bool UnsignedIntegral = Integral<T> && !SignedIntegral<T>;

, . ( , : - ). operator&& .

P Q P || Q.

, . ( , ). operator|| .

//      ( )
template <class T = void>
requires EqualityComparable<T>() || Same<T, void>
struct equal_to;

bool. , true

template<typename T> concept bool Size32 = sizeof(T) == 4;

, , .

bool, :

template<typename T> struct S {
    constexpr explicit operator bool() const { return true; }
};
template<typename T>
requires S<T>{} //   : S<T>{}   
void f(T);
f(0); // :    

requires :

1) requires, .
template<typename T>
void f(T&&) requires Eq<T>; //       

template<typename T> requires Addable<T> //      
T add(T a, T b) { return a + b; }
requires ( "requires true;"), , ( ) / requires.
2) requires, prvalue bool, . true, , false :
template<typename T>
concept bool Addable = requires (T x) { x + x; }; //  requires

template<typename T> requires Addable<T> //  requires,   requires
T add(T a, T b) { return a + b; }

template<typename T>
requires requires (T x) { x + x; } //  ,  ,
                                   //     
T add(T a, T b) { return a + b; }

requires :

requires ( -() ) { - }
- , , , , , . , . } -. ,
- , ( ). , requires.

- :

, , , -. , -requires, ,

-requires . ,

  • -requires, , .
  • -requires , " " ,
  • -requires , , :
template<class T> concept bool C = requires {
    new int[-(int)sizeof(T)]; //    T:  ,
                              //   
};

. , ( ). , , .

template<typename T>
concept bool Addable =
requires (T a, T b) {
    a + b; // " a+b   ,   "
};

//      ( )
template <class T, class U = T>
concept bool Swappable = requires(T&& t, U&& u) {
    swap(std::forward<T>(t), std::forward<U>(u));
    swap(std::forward<U>(u), std::forward<T>(t));
};

typename , . , ( ): , , , .

template<typename T> using Ref = T&;
template<typename T> concept bool C =
requires {
    typename T::inner; //    
    typename S<T>;     //    
    typename Ref<T>;   //    
};

//     ( )
template <class T, class U> using CommonType = std::common_type_t<T, U>;
template <class T, class U> concept bool Common =
requires (T t, U u) {
    typename CommonType<T, U>; // CommonType<T, U>    
    { CommonType<T, U>{std::forward<T>(t)} }; 
    { CommonType<T, U>{std::forward<U>(u)} }; 
};

{ } noexcept() --() ;

:

1) ( )
2) noexcept, noexcept ( )
3) -- , , ( )
4) -- , , :
4a) , -- ( )
4b) ( )
template<typename T> concept bool C2 =
requires(T x) {
    {*x} -> typename T::inner; //  *x   
                               //   T::inner   
                               //   *x     T::inner
};

//      ( )
template <class T, class U> concept bool Same = std::is_same<T,U>::value;
template <class B> concept bool Boolean =
requires(B b1, B b2) {
    { bool(b1) }; //      
    { !b1 } -> bool; //  
    requires Same<decltype(b1 && b2), bool>; //  ,  
    requires Same<decltype(b1 || b2), bool>;
};

-requires, . ( ), , ( requires, requires, , , )

//     
template <class T>
concept bool Semiregular = DefaultConstructible<T> &&
    CopyConstructible<T> && Destructible<T> && CopyAssignable<T> &&
requires(T a, size_t n) {  
    requires Same<T*, decltype(&a)>;  // : "Same<...>   true"
    { a.~T() } noexcept;  // : "a.~T()"  ,
                          //    
    requires Same<T*, decltype(new T)>; // : "Same<...>   true"
    requires Same<T*, decltype(new T[n])>; // 
    { delete new T };  // 
    { delete new T[n] }; // 
};

, ( ) : , -.

, - ( )

1) void f(Concept); std::vector<Concept> x = ...;
2) template<Concept T> void f();
3) Concept{T} struct X;
4) - template<typename T> void f() requires Concept<T>;
template<typename T> concept bool C() { return true; } // #1
template<typename T, typename U> concept bool C() { return true; } // #2
void f(C); //  ,    C,   #1  #2;
           //   ( )  #1.

, , ( , ), , . (, , ). -,

1) , , , .
template<typename T> concept bool C1() { return true; } // #1
template<typename T, typename U> concept bool C1() { return true; } // #2
void f1(const C1*); // < >  <T>,  #1
2) , , , , .
template<typename T> concept bool C1() { return true; } // #1
template<typename T, typename U> concept bool C1() { return true; } // #2
void f2(C1<char>); // < , char>  <T, U>,  #2
3) , ,
template<typename... Ts>
concept bool C3 = true;
C3{T} void q2();     // OK: <T>  <...Ts>
C3{...Ts} void q1(); // OK: <...Ts>  <...Ts>
4) ,
template<typename T> concept bool C() { return true; } // #1
template<typename T, typename U> concept bool C() { return true; } // #2

template <typename T>
void f(T) requires C<T>(); //  #1

. ( ) , , . , (, , ), . , ( ).

- , , , . , .

template<typename T> concept bool C2() { return true; }
template<int T> concept bool C2() { return true; }

template<C2<0> T> struct S1; // : < , 0>   
                             //  <typename T>  <int T>
template<C2 T> struct S2; //  #1  #2: 

requires , , , , , , .

, P Q, , P Q ( N >= 0 N > 0)

, P , Q , :

  • A A
  • A A||B A&&B
  • A&&B A, A||B A

, :

D1 D2 , D1 D2 ( D1 , D2 ), , D1 , D2. D1 , D2, D2 , D1, D1 , D2.

template<typename T>
concept bool Decrementable = requires(T t) { --t; };
template<typename T>
concept bool RevIterator = Decrementable<T> && requires(T t) { *t; };

// RevIterator  Decrementable,   
// RevIterator  ,  Decrementable

void f(Decrementable); // #1
void f(RevIterator);   // #2

f(0);       // int   Decrementable,  #1
f((int*)0); // int*   ,  #2   

void g(auto);          // #3 ()
void g(Decrementable); // #4

g(true);  // bool   Decrementable,  #3
g(0);     // int  Decrementable,  #4,     

concept, requires

GCC >= 6.1 ( -fconcepts)


Web Proxy Viewer  |  New URL  |  Original Page