c++11 rvalue-reference

c++11 - ¿Por qué utilizar la identidad en la definición de reenvío para la referencia de valor de C++ 0x?



rvalue-reference (1)

En Una breve introducción a las referencias de valores , forward se define como sigue:

template <typename T> struct identity { typedef T type; }; template <typename T> T &&forward(typename identity<T>::type &&a) { return a; }

¿Qué propósito realiza la clase de identity ? Por qué no:

template <typename T> T &&forward(T &&a) { return a; }


El propósito de la identity era hacer que T no fuera deducible. Es decir, para forzar al cliente a suministrar explícitamente T al forward .

forward(a); // compile-time error forward<A>(a); // ok

La razón por la que esto es necesario es porque el parámetro de plantilla es el conmutador con el que el cliente le dice al compilador que reenvíe el argumento como un valor de l o como un valor de r. Si accidentalmente olvida proporcionar esta información, los valores de l se devuelven siempre como valores de l y los valores de r se devuelven siempre como valores de r. Mientras que al principio eso puede sonar como lo que quieres, realmente no lo es.

template <class T, class A1> std::shared_ptr<T> factory(A1&& a1) { return std::shared_ptr<T>(new T(std::forward<A1>(a1))); }

En el ejemplo anterior, a1 es siempre un valor l. Pero el "interruptor" A1 puede o no ser una referencia de valor l. Si es una referencia de valor l, a1 se devuelve como valor l, de lo contrario, a1 se devuelve como valor r. Si el autor de la fábrica olvida accidentalmente el suministro de A1, el uso de la identity le recuerda en el momento de la compilación.

Nota: El borrador final carece de identity , pero usa remove_reference en el mismo lugar para el mismo propósito.