С++ rvalue reference и константный определитель - программирование
Подтвердить что ты не робот

С++ rvalue reference и константный определитель

Среди многих преимуществ сотенной квалификации - сделать API более понятным, например:

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

С введением ссылок rvalue можно получить отличную переадресацию, но часто удаляются конструкторы const, например:

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

Помимо документации, есть ли хороший способ описать, что функция2 не изменит свой вход?

4b9b3361

Ответ 1

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

Помимо документации, есть ли хороший способ описать это функция2 не изменит свой вход?

Да. Придерживайтесь решения С++ 03:

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

Преимущества совершенной пересылки - это то, что вы не хотите предполагать, что что-то есть const или не const, lvalue или rvalue. Если вы хотите, чтобы что-то не было изменено (т.е. Оно const), тогда явным образом скажу это, добавив const.

Вы можете сделать это:

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

Однако все, кто читает ваш код, задаются вопросом, почему вы использовали ссылки rvalue. И function1 перестало бы принимать lvalues. Просто используйте const &, и все поймут. Это простая и понятная идиома.

Вы не хотите идеально продвигаться вперед. Вы хотите обеспечить неизменность.

Ответ 2

Вы могли бы сказать следующее:

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

где у вас есть что-то вроде:

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

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

Таким образом, шаблон будет использоваться только в том случае, если универсальная ссылка является либо константной ссылкой (so T = U const &), либо ссылкой rvalue (поэтому T не является ссылкой).


Тем не менее, если аргумент не будет изменен, вы можете просто использовать T const & и сделать с ним, так как ничего не может быть связано с привязкой к временным значениям.