转发模板参数的常量性,我应该使用转发引用吗?

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

这正是您正在做的。