为什么需要std :: forward,默认情况下编译器不能正确执行

时间:2017-08-24 14:03:23

标签: c++ c++11 std forward

std::forward是条件转换时,为什么编译器在看到用户试图传递给其他函数的参数作为通用引用时,不能自动完成工作。

意味着为什么编译器会通过编写std::forward来为用户做正确的事情。

以有效的现代C ++为例。

void process(const Widget& lvalArg); // process lvalues
void process(Widget&& rvalArg); // process rvalues

template<typename T> // template that passes
void logAndProcess(T&& param) // param to process
{
    auto now = // get current time
    std::chrono::system_clock::now();
    makeLogEntry("Calling 'process'", now);
    process(std::forward<T>(param));
}

在上面的代码示例中,我知道删除std::forward将为进程选择不正确的重载,但是为了用户需要编写std::forward而选择正确的重载是正确的,我的意思是无法编译为我们以及不想做正确事情的用户做明显的事情,我们可以改为std::dont_forward

我可能会遗漏一些用例,其中编译器可能会混淆正确但在上面的情况下,param是通用引用和给编译器的两个重载过程我没有看到任何混淆。

只是为了解释这个问题是如何不同的,它不是为什么我们在当前的编译器行为中需要'std :: forward',而是为什么cant编译器默认情况下显而易见的是在转发引用时调用正确的函数重载周围,​​包括检测多次使用和在最后一次使用时施放到右值。

1 个答案:

答案 0 :(得分:1)

作为命名参数,param始终是左值。这意味着如果没有std::forwardprocess(param);将始终调用左值超载。

另一方面,您需要告诉编译器何时要将其明确转换为rvalue;编译器无法为您做出决定。 e.g。

process(param);                  // you don't want param to be passed as rvalue and thus might be moved here
...
process(std::forward<T>(param)); // it's fine to be moved now