usps meaning mail consigned c++ c++11 language-lawyer move-semantics rvalue-reference

c++ - meaning - usps



¿Qué es el uso del ref-qualifier `const &&`? (4)

Podemos encontrar una exploración similar de este problema en el artículo ¿Para qué sirven las referencias const rvalue? y el único uso que se destacó es este ejemplo de la biblioteca estándar:

template <class T> void ref (const T&&) = delete; template <class T> void cref (const T&&) = delete;

que deshabilita ref y cref para cref por completo. Podemos encontrar estas declaraciones en el párrafo 2 de la sección 20.8 estándar de C ++ 11 borrador objetos .

Scott Meyers alude a este uso en Referencias Universales en C ++ 11 :

Incluso la simple adición de un calificador const es suficiente para deshabilitar la interpretación de "&&" como referencia universal:

He estado cavando un poco alrededor de ref-qualifiers, siguiendo una pregunta anterior.

Dado el ejemplo de código a continuación;

#include <iostream> #include <string> #include <utility> struct A { std::string abc = "abc"; std::string& get() & { std::cout << "get() &" << std::endl; return abc; } std::string get() && { std::cout << "get() &&" << std::endl; return std::move(abc); } std::string const& get() const & { std::cout << "get() const &" << std::endl; return abc; } std::string get() const && { std::cout << "get() const &&" << std::endl; return abc; } }; int main() { A a1; a1.get(); const A a2{}; a2.get(); A().get(); const A a3{}; std::move(a3).get(); }

Y la salida es como cabría esperar:

obtener() &
get () const y
obtener() &&
get () const &&

Esto compila y ejecuta con clang y gcc 4.9.1 (aunque no 4.9.0). Muestra en vivo aquí .

En el código general (el ejemplo está allí para ver cómo se compila y ejecuta el código).

  • ¿Cuál sería el propósito del const && ref-qualifier en un método?

El método no puede modificar el contenido del objeto (es const ), un intento de return std::move(abc); desde el método const && realmente no se mueve la std::string en absoluto. Es de suponer que desearía poder modificar el objeto, ya que es un valor r y no estará disponible por mucho tiempo. Si se eliminara el método calificado de const && , el código std::move(a3).method() se vincularía al método calificado const & , lo que tendría sentido.

  • ¿Cuál sería la diferencia semántica implícita entre un método calificado como const & y uno calificado como const && ? Por ejemplo, ¿cómo variaría la implementación o por qué querría ambos?
  • ¿Sería la std::string realmente capaz de ser "movida" fuera del objeto temporal?
  • ¿Qué aspecto tendría una firma "canónica" para std::string get() const && en este caso?

Supongamos que tenemos un tipo con un estado mutable . Entonces const&& nos permitirá mutar ese estado e indicar que dicha mutación es segura.

struct bar; struct foo { mutable std::vector<char> state; operator bar() const&; operator bar() const&&; };

const no es absoluto

Salvo el estado mutable, no es seguro desechar la const en un método const&& para extraer el estado, porque extraer el estado de esta manera de un objeto const actual es un comportamiento indefinido.


Veo dos usos principales para ref-calificar un método. Una es como muestra en su método get() && , donde lo usa para seleccionar una implementación potencialmente más eficiente que solo está disponible cuando sabe que el objeto ya no se usará. Pero el otro es una sugerencia de seguridad para evitar llamar a ciertos métodos en objetos temporales.

Puede usar la notación como get() const && = delete en tales casos, aunque de manera realista guardaría este enfoque para modificar métodos, especialmente aquellos que son potencialmente costosos. No tiene mucho sentido mutar y luego desechar un objeto sin recuperar algo, y doblemente si es caro realizar la mutación. Esta construcción le da al compilador una forma de marcar y prevenir tal uso.


Sobre la utilidad de const&& ... (en general)

La utilidad del calificador const&& en el método miembro es, en el mejor de los casos, mínima. El objeto no se puede modificar de la misma manera que un método && permitiría que se modifique; es const después de todo (como se señaló, mutable sí cambia esto). Por lo tanto, no podremos arrancarle las entrañas, ya que lo temporal está expirando de todos modos, como lo haríamos en algo similar a un move normal.

De muchas maneras, la utilidad de const&& puede evaluarse mejor en el contexto de cuán útil es comenzar con un objeto de tipo const T&& . ¿Qué tan útil es un argumento de función const T&& ? Como se señala en otra respuesta (a esta pregunta) here , son muy útiles para declarar funciones eliminadas, por ejemplo, en este caso

template <class T> void ref (const T&&) = delete;

para evitar explícitamente que los objetos de los tipos de categoría prvalue y xvalue se utilicen con las funciones, y const T&& se enlaza con todos los objetos prvalue y xvalue .

¿Cuál es la utilidad de const&& method qualifier?

Es interesante observar que en la propuesta de extensiones de la biblioteca C ++ , optional , § 5.3, incluye sobrecargas, por ejemplo,

constexpr T value() const &&;

que están calificados como const&& y están especificados para realizar la misma acción que la alternativa && .

La razón que puedo inferir para este caso; Es que esto es por integridad y corrección. Si se llama al método value() en un valor de r, entonces realiza la misma acción independientemente de que sea const o no. El objeto contenido que se está moviendo o el código de cliente que lo usa deben tratar la const . Si hay algún estado mutable con el objeto contenido, entonces ese estado puede ser legítimamente cambiado.

Puede que todavía haya algún mérito en esto; en ningún orden en particular ...

  • Para declararlo = delete para prohibir el uso del método en valores predefinidos y valores.
  • Si el tipo tiene un estado mutable y el calificador tiene sentido (posiblemente además de los otros calificadores) en el entorno de destino, considérelo.
  • Si está implementando un tipo de contenedor genérico, entonces, para completar y corregir , considere agregarlo y realizar la misma acción que el método && . El consejo aquí es una especie de la biblioteca estándar (y sus extensiones).

¿Qué aspecto tendría una firma "canónica" para un método cualificado de const&& ?

Dado que el método realizará la misma acción que el método && , recomendaría que la firma coincida con la firma && .