5

我想编写一个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()是 non- const,但foo()需要它的参数是const

作为一个模板函数,foo()应该const与非仿函数一起使用const,并且不要对其参数的 -ness 挑剔const

如果我foo()通过删除const以下内容进行更改:

template <typename T> void foo(T& x) { /* ... */ }

...它也不起作用,因为您无法将右值引用转换为非const左值引用,因此foo(MyFunctor{})无法调用。

更改foo()为转发参考可以解决所有问题:

template <typename T> void foo(T&& x) { /* ... */ }

但这是“正确”的方式吗?转发引用不应该只用于std::forward()(即除了将其转发到另一个函数之外,不应触及参数)吗?

4

2 回答 2

4

是的,转发引用是正确的方法,如果它能让你平静下来,你当然可以转发参数:

template <typename T> void foo(T&& x){
    std::forward<T>(x)();
}

现在它甚至可以与 ref 合格的呼叫运算符一起使用。

于 2017-05-03T10:02:23.460 回答
0

是的,这就是转发引用的全部目的。

除了将其转发到另一个函数之外,不应触及该参数

这正是您正在做的事情。

于 2017-05-03T10:06:14.517 回答