当我已经有一个参数被作为右值引用时,我是否需要使用移动构造函数?

问题描述 投票:0回答:1
class EntityBase {
public:
    EntityBase() { std::cout << "EntityBase constructor called." << std::endl; }
    EntityBase(const std::string& name) : m_name(name) { std::cout << "EntityBase constructor string called." << std::endl; }
    EntityBase(std::string&& name) : m_name(std::move(name)) { std::cout << "EntityBase constructor string&& called." << std::endl; }
    ~EntityBase() { std::cout << "EntityBase destructor called." << std::endl; }
    private:
    std::string m_name;
};

在第二个构造函数中,我已经将 name 作为右值引用,所以我需要使用

std::move(name)
调用吗?

如何编写一个可以同时接受左值和右值引用并根据引用类型移动或复制参数的构造函数?

我希望我们不需要使用移动构造函数,因为我们已经将参数的类型捕获为右值引用。

c++11 c++17 move move-semantics
1个回答
0
投票

当我已经有一个参数被作为右值引用时,我是否需要使用移动构造函数?

是的,因为

name
有名字,当用作表达式时,它的值类别是左值。声明的类型(与表达式的值类别不同)是
rvalue reference
并不重要。

如何编写一个可以同时接受左值和左值的构造函数 右值引用并根据引用的类型移动或复制 争论?

您需要一个模板,

template <typename String>
explicit EntityBase(String&& name): m_name{std::forward<String>(name)}{}

您可能希望添加额外的 SFINAE 检查,以确保

String
确实是您期望的类型。另外,对于单参数构造函数,您通常应该将构造函数设为
explicit

或者,如果您不介意在左值情况下进行额外的移动,则可以仅按值获取字符串,然后始终执行移动,这将正确处理左值和右值。

explicit EntityBase(std::string name) : m_name{std::move(name)}{}
© www.soinside.com 2019 - 2024. All rights reserved.