c++ - 为什么需要 std::forward,默认情况下编译器不能做正确的事情

标签 c++ c++11 std forward

<分区>

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

意味着为什么编译器会通过编写 std::forward 的方式将做正确事情的责任放在用户身上。

以 Effective modern 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 将为 process 选择不正确的重载,但是为了选择正确的重载做正确的事情,为什么用户需要编写 std::forward,我的意思是编译器不能为我们和不想做正确事情的用户做显而易见的事情,我们可以用 std::dont_forward 代替。

我可能遗漏了一些用例,在这些用例中,编译器可能会混淆什么是正确的,但在上述情况下,param 是通用引用,并且为编译器提供了两个进程重载,我没有看到任何混淆。

只是为了解释这个问题有何不同,它不是关于为什么我们在当前编译器行为中需要“std::forward”,而是为什么编译器不能默认执行明显的操作,即在传递引用时调用正确的函数重载around ,包括检测多次使用并在最后一次使用时转换为右值。

最佳答案

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

另一方面,当你想显式地将它转换为右值时,你需要告诉编译器;编译器无法为您做出决定。例如

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

关于c++ - 为什么需要 std::forward,默认情况下编译器不能做正确的事情,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45863721/

相关文章:

c++ - 如果 `double` 或 `long double` 适合 `long long`,如何正确检查?

c++ - 如何使用需要非常量引用的函数编写 decltype 表达式?

c++ - 具有递归继承和使用声明的可变参数模板

c++ - 从成对 vector 中获取唯一元素的有效方法

c++ - 如何让非成员 get<N> 为命名空间中的自定义类工作 [C++17]

c++ - 你如何清除一个 std::ostringstream 实例以便它可以被重用?

c++ - 如何附加到现有的共享内存段

c++ 从数组继承 darray

c++ - 使用 boost 正则表达式解析文本文件

c++ - cin 到 boolean vector