llowed to have non
equality-preserving  requires  expressions:

  * [ ` output_iterator ` ](/w/cpp/iterator/output_iterator "cpp/iterator/output iterator")
  * [ ` indirectly_writable ` ](/w/cpp/iterator/indirectly_writable "cpp/iterator/indirectly writable")
  * [ ` invocable ` ](/w/cpp/concepts/invocable "cpp/concepts/invocable")
  * [ ` weakly_incrementable ` ](/w/cpp/iterator/weakly_incrementable "cpp/iterator/weakly incrementable")
  * [ ` range ` ](/w/cpp/ranges/range "cpp/ranges/range")

###  [ [ edit ](/mwiki/index.php?title=cpp/concepts&action=edit&section=2
"Edit section: Implicit expression variations") ]  Implicit expression
variations

A [ requires  expression ](/w/cpp/language/requires "cpp/language/requires")
that uses an expression that is non-modifying for some constant lvalue operand
also implicitly requires additional variations of that expression that accept
a non-constant lvalue or (possibly constant) rvalue for the given operand
unless such an expression variation is explicitly required with differing
semantics.

These _implicit expression variations_ must meet the same semantic
requirements of the declared expression. The extent to which an implementation
validates the syntax of the variations is unspecified.

    
    
    template<class T>
    concept C = requires(T a, T b, const T c, const T d)
    {
        c == d;           // expression #1: does not modify the operands
        a = std::move(b); // expression #2: modifies both operands
        a = c;            // expression #3: modifies the left operand `a`
    };
     
    // Expression #1 implicitly requires additional expression variations that
    // meet the requirements for c == d (including non-modification),
    // as if the following expressions had been declared as well:
     
    // ------ const == const ------- ------ const == non-const ---
    //                                         c  ==           b;
    //            c == std::move(d);           c  == std::move(b);
    // std::move(c) ==           d;  std::move(c) ==           b;
    // std::move(c) == std::move(d); std::move(c) == std::move(b);
     
    // -- non-const == const ------- -- non-const == non-const ---
    //           a  ==           d;            a  ==           b;
    //           a  == std::move(d);           a  == std::move(b);
    // std::move(a) ==           d;  std::move(a) ==           b;
    // std::move(a) == std::move(d); std::move(a) == std::move(b);
     
    // Expression #3 implicitly requires additional expression variations that
    // meet the requirements for a = c
    // (including non-modification of the second operand),
    // as if the expressions a = b (non-constant lvalue variation)
    // and a = std::move(c) (const rvalue variation) had been declared.
     
    // Note: Since expression #2 already requires the non-constant rvalue variation
    // (a == std::move(b)) explicitly, expression #3 does not implicitly require it anymore.
     
    // The type T meets the explicitly stated syntactic requirements of
    // concept C above, but does not meet the additional implicit requirements
    // (i.e., T satisfies but does not model C):
    // a program requires C<T> is ill-formed (no diagnostic required).
    struct T
    {
        bool operator==(const T&) const { return true; }
        bool operator==(T&) = delete;
    };

###  [ [ edit ](/mwiki/index.php?title=cpp/concepts&action=edit&section=3
"Edit section: Standard library concepts") ]  Standard library concepts

Defined in namespace ` std `  
---  
  
#####  Core language concepts  
  
Defined in header ` [ <concepts> ](/w/cpp/header/concepts
"cpp/header/concepts") `  
[ same_as  ](/w/cpp/concepts/same_as "cpp/concepts/same as") (C++20)  |  specifies that a type is the same as another type   
(concept)  [ [edit]
](https://en.cppreference.com/mwiki/index.php?title=Template:cpp/concepts/dsc_same_as&action=edit)  
[ derived_from  ](/w/cpp/concepts/derived_from "cpp/concepts/derived from"