以下哪项是 std::move 的正确用法
Which of these is the proper usage of std::move
我正在尝试更改我的代码以使用 std::move 按值获取向量,而不是通过引用传递它,因为我发现这样做效率更高。不过,我已经看到了不同的方法,一种是让构造函数按值传递并在构造函数中使用 std::move,另一种方法是用 std::move 初始化 class 和让构造函数采用右值(我做对了吗?)。下面的一些例子:
方法一:
构造函数:
StatisticsCompiler::StatisticsCompiler(std::vector<Wrapper<StatisticsMC>> Inner_) :Inner(std::move(Inner_))
{
}
主要内容:
vector<Wrapper<StatisticsMC>> gathererArray{ meanGatherer, absQuantileGatherer, relVaRGatherer, relESGatherer };
StatisticsCompiler gathererCombiner(gathererArray);
方法二
构造函数:
StatisticsCompiler::StatisticsCompiler(std::vector<Wrapper<StatisticsMC>>&& Inner_) :Inner(Inner_)
{
}
主要内容:
vector<Wrapper<StatisticsMC>> gathererArray{ meanGatherer, absQuantileGatherer, relVaRGatherer, relESGatherer };
StatisticsCompiler gathererCombiner(std::move(gathererArray));
这里发生的事情之间有区别还是同一件事,第一种方法 "looks" 在 main 中更好,但第二种方法是我通过学习右值直观地理解它的工作方式.如果性能方面它们完全相同,那么标准做法是什么?
StatisticsCompiler::StatisticsCompiler(std::vector<Wrapper<StatisticsMC>> Inner_) :Inner(std::move(Inner_))
此构造函数按值获取参数。参数可以是从左值参数复制构造的,也可以是从右值移动构造的。这种在从左值复制和从右值移动之间进行选择的能力,加上简单性,是推荐这种方法的原因。
成员总是从复制或移动的参数中移动。
StatisticsCompiler gathererCombiner(gathererArray);
你传递了一个左值;因此参数被复制。您可以通过传递右值来使用移动构造函数:
StatisticsCompiler gathererCombiner(std::move(gathererArray));
或者您甚至可以使用纯右值:
StatisticsCompiler gathererCombiner({
meanGatherer,
absQuantileGatherer,
relVaRGatherer,
relESGatherer,
});
StatisticsCompiler::StatisticsCompiler(std::vector<Wrapper<StatisticsMC>>&& Inner_) :Inner(Inner_)
这个构造函数只接受右值参数。这不像第一个建议那样灵活,它也可以接受左值。
这种方法总是将参数复制到成员中。您可能想搬家:
Inner(std::move(Inner_))
结论:当你想存储一个作为参数给定的对象时,按值传递(第一个例子)是很好的默认选择。如果以后不需要传递的参数,则可以选择从中移动。
我正在尝试更改我的代码以使用 std::move 按值获取向量,而不是通过引用传递它,因为我发现这样做效率更高。不过,我已经看到了不同的方法,一种是让构造函数按值传递并在构造函数中使用 std::move,另一种方法是用 std::move 初始化 class 和让构造函数采用右值(我做对了吗?)。下面的一些例子:
方法一:
构造函数:
StatisticsCompiler::StatisticsCompiler(std::vector<Wrapper<StatisticsMC>> Inner_) :Inner(std::move(Inner_))
{
}
主要内容:
vector<Wrapper<StatisticsMC>> gathererArray{ meanGatherer, absQuantileGatherer, relVaRGatherer, relESGatherer };
StatisticsCompiler gathererCombiner(gathererArray);
方法二
构造函数:
StatisticsCompiler::StatisticsCompiler(std::vector<Wrapper<StatisticsMC>>&& Inner_) :Inner(Inner_)
{
}
主要内容:
vector<Wrapper<StatisticsMC>> gathererArray{ meanGatherer, absQuantileGatherer, relVaRGatherer, relESGatherer };
StatisticsCompiler gathererCombiner(std::move(gathererArray));
这里发生的事情之间有区别还是同一件事,第一种方法 "looks" 在 main 中更好,但第二种方法是我通过学习右值直观地理解它的工作方式.如果性能方面它们完全相同,那么标准做法是什么?
StatisticsCompiler::StatisticsCompiler(std::vector<Wrapper<StatisticsMC>> Inner_) :Inner(std::move(Inner_))
此构造函数按值获取参数。参数可以是从左值参数复制构造的,也可以是从右值移动构造的。这种在从左值复制和从右值移动之间进行选择的能力,加上简单性,是推荐这种方法的原因。
成员总是从复制或移动的参数中移动。
StatisticsCompiler gathererCombiner(gathererArray);
你传递了一个左值;因此参数被复制。您可以通过传递右值来使用移动构造函数:
StatisticsCompiler gathererCombiner(std::move(gathererArray));
或者您甚至可以使用纯右值:
StatisticsCompiler gathererCombiner({
meanGatherer,
absQuantileGatherer,
relVaRGatherer,
relESGatherer,
});
StatisticsCompiler::StatisticsCompiler(std::vector<Wrapper<StatisticsMC>>&& Inner_) :Inner(Inner_)
这个构造函数只接受右值参数。这不像第一个建议那样灵活,它也可以接受左值。
这种方法总是将参数复制到成员中。您可能想搬家:
Inner(std::move(Inner_))
结论:当你想存储一个作为参数给定的对象时,按值传递(第一个例子)是很好的默认选择。如果以后不需要传递的参数,则可以选择从中移动。