Namespaces
Variants

std:: indirectly_writable

From cppreference.net
Iterator library
Iterator concepts
Iterator primitives
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Range access
(C++11) (C++14)
(C++14) (C++14)
(C++11) (C++14)
(C++14) (C++14)
(C++17) (C++20)
(C++17)
(C++17)
Definido en el encabezado <iterator>
template < class Out, class T >

concept indirectly_writable =
requires ( Out && o, T && t ) {
* o = std:: forward < T > ( t ) ;
* std:: forward < Out > ( o ) = std:: forward < T > ( t ) ;
const_cast < const std:: iter_reference_t < Out > && > ( * o ) = std:: forward < T > ( t ) ;
const_cast < const std:: iter_reference_t < Out > && > ( * std:: forward < Out > ( o ) ) =
std:: forward < T > ( t ) ;
} ;

/* ninguna de las cuatro expresiones anteriores necesita preservar la igualdad */
(desde C++20)

El concepto indirectly_writable < Out, T > especifica los requisitos para escribir un valor cuyo tipo y categoría de valor están codificados por T en el objeto referenciado de un iterador Out .

Requisitos semánticos

Sea e una expresión tal que decltype ( ( e ) ) es T , y o un objeto desreferenciable de tipo Out , entonces indirectly_writable < Out, T > se modela solo si:

o no es necesario que sea desreferenciable después de evaluar cualquiera de las expresiones de asignación anteriores. Si e es un xvalue, el estado resultante del objeto que denota es válido pero no especificado.

Preservación de la igualdad

Las expresiones declaradas en las requires expressions de los conceptos de la biblioteca estándar deben ser equality-preserving (excepto cuando se indique lo contrario).

Notas

El único uso válido de operator * es en el lado izquierdo de una expresión de asignación. La asignación a través del mismo valor de un tipo indirectamente escribible puede ocurrir solo una vez.

Las expresiones requeridas con const_cast evitan que objetos indirectly_readable con tipos prvalue reference satisfagan los requisitos sintácticos de indirectly_writable por accidente, mientras permiten que las referencias proxy continúen funcionando siempre que su constancia sea superficial. Consulte Ranges TS issue 381 .

struct Object
{
    Object& operator=(const Object& other) = default;
    int x;
};
struct ProxyReference
{
    ProxyReference& operator=(const ProxyReference& other) = default;
    const ProxyReference& operator=(const Object& o) const
    {
        *p = o;
        return *this;
    }
    Object* p;
};
struct I1 { Object& operator*(); };
struct I2 { Object operator*(); };
struct I3 { ProxyReference operator*(); };
static_assert(std::indirectly_writable<I1, Object>);
static_assert(!std::indirectly_writable<I2, Object>);
static_assert(std::indirectly_writable<I3, Object>);
static_assert(!std::indirectly_writable<I3, ProxyReference>);
void f(I1 i1, I2 i2, I3 i3, Object o)
{
    *i1 = o;  // OK, asigna al valor referenciado por *i1
    *i2 = o;  // OK, pero sin sentido: Esto asigna al temporal devuelto por *i2
    *i3 = o;  // OK, llama a ProxyReference::operator=(const Object& o) const
              // que ejecuta *ptr = o, donde ptr es (*i3).p
}