转发模板参数的常量性,我应该使用转发引用吗?
Forwarding the const-ness of a template parameter, should I use a forwarding reference?
我想编写一个函数 foo
,它应该调用其参数的 operator()
,如下面的(损坏的)代码所示:
template <typename T> void foo(const T& x){
x();
}
struct MyFunctor{
int data;
void operator()(){
/* stuff that might modify the data */
}
};
int main()
{
foo(MyFunctor{});
}
显然代码不起作用,因为operator()
是非const
,但是foo()
要求它的参数是const
.
作为模板函数,foo()
应该与 const
和非 const
仿函数一起使用,并且不要对其参数的 const
特性挑剔.
如果我通过将 const
删除为以下内容来更改 foo()
:
template <typename T> void foo(T& x) { /* ... */ }
...它也不会工作,因为您不能将右值引用转换为非const
左值引用,因此无法调用foo(MyFunctor{})
。
将 foo()
更改为转发引用可解决所有问题:
template <typename T> void foo(T&& x) { /* ... */ }
但这是 "right" 方式吗?转发引用不应该只与 std::forward()
一起使用(即除了将参数转发给另一个函数外不应该触及参数)?
是的,转发引用才是正路,如果能让你安心,当然可以转发参数:
template <typename T> void foo(T&& x){
std::forward<T>(x)();
}
现在它甚至可以与 ref-qualified 调用运算符一起使用。
是的,这就是转发引用的全部目的。
the parameter shouldn't be touched apart from forwarding it to another function
这正是您正在做的。
我想编写一个函数 foo
,它应该调用其参数的 operator()
,如下面的(损坏的)代码所示:
template <typename T> void foo(const T& x){
x();
}
struct MyFunctor{
int data;
void operator()(){
/* stuff that might modify the data */
}
};
int main()
{
foo(MyFunctor{});
}
显然代码不起作用,因为operator()
是非const
,但是foo()
要求它的参数是const
.
作为模板函数,foo()
应该与 const
和非 const
仿函数一起使用,并且不要对其参数的 const
特性挑剔.
如果我通过将 const
删除为以下内容来更改 foo()
:
template <typename T> void foo(T& x) { /* ... */ }
...它也不会工作,因为您不能将右值引用转换为非const
左值引用,因此无法调用foo(MyFunctor{})
。
将 foo()
更改为转发引用可解决所有问题:
template <typename T> void foo(T&& x) { /* ... */ }
但这是 "right" 方式吗?转发引用不应该只与 std::forward()
一起使用(即除了将参数转发给另一个函数外不应该触及参数)?
是的,转发引用才是正路,如果能让你安心,当然可以转发参数:
template <typename T> void foo(T&& x){
std::forward<T>(x)();
}
现在它甚至可以与 ref-qualified 调用运算符一起使用。
是的,这就是转发引用的全部目的。
the parameter shouldn't be touched apart from forwarding it to another function
这正是您正在做的。