c++ - 在这些直接在函数中使用参数的情况下,我是否需要完善前向参数?

标签 c++ perfect-forwarding

我心想我不需要std::forward<T>(arg);在我的函数中,因为我没有将参数传递给另一个函数,所以我直接使用它。然而,后来我想,即使我直接使用它,例如分配它,或使用它作为构造函数参数,那么这些都是函数调用,分别是 operator=和构造函数,这是一个函数调用:

template <typename element_T>
    void push_back(element_t&& copy)
    {
        *_end = copy; // This calls operator=, which is a function
    }

template <typename ... ConstructorArgs>
void emplace_back(ConstructorArgs&& ... args) 
    { 
        
        new (_end) element_t(args); 
// Calls constructor, needs (std::forward<ConstructorArgs>(args)...) ?

        
    }

我需要调用std::forward吗?在这些情况下?

最佳答案

作为变量名称的表达式始终是左值。例如,在

1  template <typename T>
2  void push_back(T&& copy) {
3      *_end = copy;
4  }

copy第 3 行的左值 value category无论 T 推导出什么类型。取决于如何operator=第 3 行中已定义/重载,这可能会导致选择错误的重载或错误的类型推导。

考虑以下简单示例(遵循评论部分中 Ted Lyngmo 的示例):

struct A {
    void operator=(const A&);  // (1)
    void operator=(A&&);       // (2)
};

struct C {
    template<class T>
    void push_back(T&& copy) {
        a = copy;
    }
    A a;
};

C{}.push_back(A{});

哪个A的赋值运算符会在这里被调用吗?人们可能会期望 (2),因为 A{}是纯右值,但正确答案是 (1),因为 copy is an lvalue ,并且左值不能绑定(bind)到右值引用。

如果我们将分配更改为

a = std::forward<T>(copy);

然后表达式 std::forward<T>(copy)将具有 xvalue 值类别,并且将按预期调用 (2) 赋值运算符。

新的展示位置遵循相同的推理。

关于c++ - 在这些直接在函数中使用参数的情况下,我是否需要完善前向参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67667209/

相关文章:

c++ - 如何设置 Eclipse 库路径?

c++ - 转发参数的可变参数列表

c++ - 为什么我不能在 C++ 中使用带有转发引用的特征?

c++ - 右值模板参数隐式用作左值,并且 std::forwarding 工作

c++ - 不是从 .begin()ing 迭代一个 STL 容器并环绕

c++ - 从指针访问 [] 运算符

c++ - 如何使用具有可警报 true 和总体最短 sleep 时间的 SleepEx?

c++ - 什么等同于 C/C++ 中的 java static final 成员变量?如何通过一些计算来初始化它?

c++ - 调用的返回类型仅使用类型信息而不是对象信息

c++ - 删除右值,保留左值引用(标准类型特征可用?)