2013-06-09 12 views
16

Wśród wielu zalet const kwalifikacji jest, aby API bardziej zrozumiałe, przykład:C++ RValue odniesienia i const kwalifikatora

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

Wraz z wprowadzeniem odniesienia rvalue, można skorzystać z doskonałej spedycji ale często const kwalifikacyjnych są usuwane, na przykład:

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

Czy istnieje dobry sposób na opisanie, że funkcja 2 nie zmieni swojego wkładu?

+5

Jeśli przesyłasz parametry tylko komuś innemu, co Cię obchodzi, co jest lub nie jest "const"? Pozwoliłeś im sobie z tym poradzić. –

Odpowiedz

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

Oprócz dokumentacji, czy jest to dobry sposób, aby opisać to function2 nie zmieni swój wkład?

Tak. Trzymać się z roztworu C++ 03:

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

Korzyści z doskonałej spedycji to, że nie chcą przyjąć, czy coś jest const lub nie const, lwartość lub RValue. Jeśli chcesz wymusić, że coś nie jest zmodyfikowane (to znaczy, że jest to const), możesz to wyraźnie dodać, dodając const.

Można to zrobić:

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

Jednak wszyscy, którzy czytają kod będzie się zastanawiać, dlaczego użyłeś referencje rvalue. A function1 przestałby akceptować wartości l. Po prostu użyj const &, a wszyscy zrozumieją. Jest to prosty i zrozumiały idiom.

Nie chcesz idealnie do przodu. Chcesz wymusić niezmienność.

9

można powiedzieć tak:

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

gdzie masz coś takiego:

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

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

ten sposób szablon będzie użyteczny tylko wtedy, gdy uniwersalne odniesienia jest albo const-odniesienia (tak T = U const &) lub wartością rwartości (więc T nie jest odniesieniem).


To powiedziawszy, jeśli argument nie zostanie zmieniona, można po prostu użyć T const & i być z nim zrobić, ponieważ nie ma nic do zyskania od wiązania mutably do wartości tymczasowych.

Powiązane problemy