2013-06-09 14 views
16

Tra i numerosi vantaggi di qualificazione const è quello di rendere un'API più comprensibile, ad esempio:C++ di riferimento rvalue e qualificatore const

template<typename T> int function1(T const& in); 
// clearly, the input won’t change through function1 

Con l'introduzione di riferimenti rvalue, si può beneficiare di inoltro perfetto ma qualificazioni spesso const vengono rimossi, ad esempio:

template<typename T> int function2(T&& in); 
// can explicitly forward the input if it's an rvalue 

a parte la documentazione, c'è un buon modo per descrivere che function2 non cambierà il suo ingresso?

+5

Se stai semplicemente inoltrando i parametri a qualcun altro, cosa ti importa di cosa è o non è 'const'? Lascialo che si occupino di esso. –

risposta

28
template<typename T> int function2(T&& in); 
// can explicitly forward the input if it's an rvalue 

A parte la documentazione, c'è un buon modo per descrivere che function2 non cambierà il suo ingresso?

Sì. Stick con la soluzione C++ 03:

template<typename T> int function1(T const& in); 
// clearly, the input won’t change through function1 

I vantaggi di inoltro perfetto sono che non si vuole assumere se qualcosa è const o non const, lvalue o rvalue. Se si vuole far rispettare quel qualcosa non viene modificato (vale a dire che è const), quindi esplicitamente affermarlo aggiungendo const.

Si potrebbe fare questo:

template<typename T> int function1(T const&& in); 
// clearly, the input won’t change through function1 

Tuttavia tutti coloro che hanno letto il codice verrebbe da chiedersi il motivo per cui hai utilizzato i riferimenti rvalue. E function1 smetterebbe di accettare lvalue. Basta usare const & invece e tutti capiranno. È un idioma semplice e ben compreso.

Non si desidera andare avanti perfettamente. Vuoi rafforzare l'immutabilità.

9

Si potrebbe dire questo:

template <typename T> 
typename std::enable_if<immutable<T>::value, int>::type 
function(T && in) 
{ 
    // ... 
} 

dove si ha qualcosa di simile:

template <typename T> struct immutable 
: std::integral_constant<bool, !std::is_reference<T>::value> {}; 

template <typename U> struct immutable<U const &> 
: std::true_type {}; 

In questo modo, il modello sarà solo utilizzabile se il riferimento universale, o è un const riferimento (così T = U const &) o un riferimento di rvalore (quindi T non è un riferimento).


Detto questo, se l'argomento non sta per essere cambiata, si potrebbe utilizzare T const & e da fare con esso, dal momento che non c'è niente da guadagnare da vincolante mutably a valori temporanei.

Problemi correlati