const 限定的众多好处之一是使 API 更易于理解,例如:
template<typename T> int function1(T const& in);
// clearly, the input won’t change through function1
随着右值引用的引入,人们可以从完美转发中受益,但通常会删除 const 限定符,例如:
template<typename T> int function2(T&& in);
// can explicitly forward the input if it's an rvalue
除了文档之外,还有什么好方法来描述 function2 不会改变其输入吗?
template<typename T> int function2(T&& in); // can explicitly forward the input if it's an rvalue
除了文档之外,是否有一个好的方法来描述它 function2 不会改变它的输入?
是的。坚持使用 C++03 解决方案:
template<typename T> int function1(T const& in);
// clearly, the input won’t change through function1
完美转发的好处是你不想假设某些东西是
const
还是非const
、左值还是右值。如果您想强制某些内容不被修改(即它是 const
),请通过添加 const
来明确说明。
你可以这样做:
template<typename T> int function1(T const&& in);
// clearly, the input won’t change through function1
然而,每个读过你代码的人都会想知道为什么你使用了右值引用。并且
function1
将停止接受左值。用const &
代替大家就明白了。这是一个简单易懂的习语。
你不想完美转发。您想要强制执行不变性。
你可以这样说:
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 {};
这样,只有当通用引用是常量引用(因此
T = U const &
)或右值引用(因此T
不是引用)时,模板才可用。
也就是说,如果参数不会改变,你可以只使用
T const &
并完成它,因为可变地绑定到临时值没有任何好处。