6

tengo las siguientes sobrecargas plantilla dos funciones:const unificador T & y T && sobrecarga

template<typename T> 
optional<T> some(const T& x) 
{ 
    return optional<T>(x); 
} 

template<typename T> 
typename std::enable_if<std::is_rvalue_reference<T&&>::value, optional<T> >::type 
some(T&& x) 
{ 
    return optional<T>(std::move(x)); 
} 

Mi primer intento de unificar las sobrecargas vía perfecta expedición fracasó:

template<typename T> 
optional<T> some(T&& x) 
{ 
    return optional<T>(std::forward<T>(x)); 
} 

error: forming pointer to reference type 'const std::basic_string<char>&' 

al igual que mi segundo intento:

template<typename T> 
optional<typename std::remove_reference<T>::type> some(T&& x) 
{ 
    return optional<typename std::remove_reference<T>::type>(std::forward<T>(x)); 
} 

error: no matching function for call to 
'std::basic_string<char>::basic_string(gpa::optional<const std::basic_string<char> >)' 

¿Hay una forma clara de unificar las sobrecargas, o debería simplemente vivir con ellas?

+1

Debe proporcionar una definición de lo que 'opcional <>' es. –

+0

Es básicamente un clon de juguete de 'boost :: optional'. – fredoverflow

+1

... Y sin embargo, la pregunta es, ¿puedes proporcionar la definición? Tengo la sensación de que el problema es con la interfaz de 'opcional' (es decir, el reenvío perfecto es la solución para' algunos', puede que necesite modificarlo para que quepa 'opcional') –

Respuesta

1

En general, la mejor manera de hacerlo es tomar el objeto por valor y dejar que la persona que llama decidir si copia o moverlo:

template<typename T> 
optional<T> some(T x) 
{ 
    return optional<T>(std::move(x)); 
} 

Si la persona que llama lo llama con un temporal o usa std::move en su valor, luego se mueve. De lo contrario, se copia.

Sí, esto significa que hará un movimiento adicional (que, si el movimiento es lo mismo que copiar, significa hacer dos copias). Si ese es un problema de rendimiento significativo para usted, entonces tendrá que usar la implementación de dos sobrecargas.

4

No estoy familiarizado con su optional, pero tal vez es necesario añadir:

typename remove_const<...>::type 

alrededor de sus remove_reference en dos lugares. (Debido a que su primera sobrecarga de su solución de 2 sobrecargas, que supongo está pasando todas sus pruebas, efectivamente hace un remove_const al declarar optional<T>).

+0

¿No debería ser' remove_cv' solo para ¿estar en el lado seguro? – pmr

+1

Si eso es lo que se desea. La solución actual de 2 sobrecargas solo rechaza los valores lálidos volátiles. Es difícil para mí decir lo que se desea sin un ejemplo completo de código. –

Cuestiones relacionadas