转发引用只应作为 std::forward 的参数
8.8 ID_illForwardingReference
不应混淆“转发引用(forwarding references)”与右值引用,除作为 std::forward 的参数之外,不应对转发引用再有任何操作。
转发引用是类型为 T&& 的参数,T 为函数模板类型。左值和右值均可与转发引用绑定,但如果绑定右值,右值的相关特性会被隐藏,故不应直接操作转发引用,应通过 std::forward<T> 交由合适的接口处理。
示例:
int fun(int&) { return 1; }
int fun(int&&) { return 2; }
int fun(const int&) { return 3; }
template <class T>
int wrapper(T&& arg) { // Forwarding reference
return fun(arg); // Non-compliant
}
int main() {
int n = 1;
cout << wrapper(n); // wrapper<int&>(int&)
cout << wrapper(0); // wrapper<int>(int&&)
}
例中左值 n 和右值 0 均可与转发引用 arg 绑定,但右值相关的特性被隐藏,只能调用 fun(int&),无法正确选择重载的接口。
应改为:
template <class T>
int wrapper(T&& arg) {
return func(forward<T>(arg)); // Compliant
}
对转发引用参数包也有相同要求:
template <class... V>
int wrapper(V&&... args) {
return func(forward<V>(args)...); // Compliant
}
相关
依据
ISO/IEC 14882:2011 20.2.3(1)
ISO/IEC 14882:2017 23.2.5(1)