c++ rvalue reference and const qualifier

2019-03-11 02:04发布

Among the many benefits of const qualification is to make an API more understandable, example:

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

With the introduction of rvalue references, one can benefit from perfect forwarding but often const qualifiers are removed, example:

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

Apart from documentation, is there a good way to describe that function2 won’t change its input?

标签: c++ c++11
2条回答
何必那么认真
2楼-- · 2019-03-11 02:15

You could say this:

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

where you have something like:

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

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

This way, the template will only be usable if the universal reference is either a const-reference (so T = U const &) or an rvalue-reference (so T is not a reference).


That said, if the argument is not going to be changed, you could just use T const & and be done with it, since there's nothing to be gained from binding mutably to temporary values.

查看更多
走好不送
3楼-- · 2019-03-11 02:26
template<typename T> int function2(T&& in);
// can explicitly forward the input if it's an rvalue

Apart from documentation, is there a good way to describe that function2 won’t change its input?

Yes. Stick with the C++03 solution:

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

The benefits of perfect forwarding are that you don't want to assume if something is const or non-const, lvalue or rvalue. If you want to enforce that something is not modified (i.e. that it is const), then explicitly say so by adding const.

You could do this:

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

However everyone who read your code would wonder why you've used rvalue references. And function1 would cease to accept lvalues. Just use const & instead and everyone will understand. It is a simple and well understood idiom.

You don't want to perfectly forward. You want to enforce immutability.

查看更多
登录 后发表回答