关于从函数和move返回大值的混淆 我在看Scott Mayers、萨特和Andrei Alexandrescu之间的一个古老的小组讨论,从C++到2011岁。在谈到人们会错误地使用哪种c++11(当时的c++0x)功能的问题时,Andrei提到,人们假设从函数返回大值时移动语义不会涉及成本是错误的

关于从函数和move返回大值的混淆 我在看Scott Mayers、萨特和Andrei Alexandrescu之间的一个古老的小组讨论,从C++到2011岁。在谈到人们会错误地使用哪种c++11(当时的c++0x)功能的问题时,Andrei提到,人们假设从函数返回大值时移动语义不会涉及成本是错误的,c++,c++11,move-semantics,rvalue-reference,C++,C++11,Move Semantics,Rvalue Reference,例如,我现在不会设计按值返回大对象的接口 纯粹的原因是,对于所有的r值参考,有 有很多情况下,不必要的副本将被删除 创建。这一点不应该被忘记 我不设计,也不宽恕设计返回的接口 按价值衡量大事,因为总有一天会有人从 it和分配将是低效的 我不认为归还大件物品的成本应该被忘记 r值参考的胜利的后果 赫伯对此阐述如下: 我同意你的观点,但这是两种不同的情况,一种是你 产生一个新的结果,你知道你会把它放在某个地方, 这就是你通过一个非常量引用传入,然后有一个out 参数,这就是out参数的用途 在其他情

例如,我现在不会设计按值返回大对象的接口 纯粹的原因是,对于所有的r值参考,有 有很多情况下,不必要的副本将被删除 创建。这一点不应该被忘记

我不设计,也不宽恕设计返回的接口 按价值衡量大事,因为总有一天会有人从 it和分配将是低效的

我不认为归还大件物品的成本应该被忘记 r值参考的胜利的后果

赫伯对此阐述如下:

我同意你的观点,但这是两种不同的情况,一种是你 产生一个新的结果,你知道你会把它放在某个地方, 这就是你通过一个非常量引用传入,然后有一个out 参数,这就是out参数的用途

在其他情况下,您有两个输入,您将 做一些新的东西,它会以价值回报,而不是以价值回报 out参数是一个对象,但它按值返回,而不是执行 如今,堆分配的笨拙解决方案很容易出错 返回指针,只是为了避免额外的副本

这是怎么回事,我只是不明白这两个家伙在说什么。 安德烈所说的“从it分配”的成本有什么不同? 赫伯的解释也在我脑海中闪过。谁能详细说明一下吗

还考虑以下代码:

vector<BigData> GetVector(int someIndex)
{
   vector<BigData> toFill;
   // some processing
   // filling the vector
   return toFill;
}
vector GetVector(int-someIndex)
{
向量toFill;
//一些加工
//填充向量
返乡;
}
我认为move语义将使上述代码等效于将空向量作为out参数传递。这不是吗


这里有一个链接到。以上几点是在41分钟左右的比赛时间后提出的。

我看不懂赫伯、安德烈或斯科特的心思。(旁白:这些人——都很有才华——都与阿波罗太空计划(视频中的背景)毫无关系)。不过,我可以对右值引用/移动语义添加一些见解

如果您有纯工厂功能,如:

vector<BigData>
GetVector(int someIndex)
{
   vector<BigData> toFill;
   // some processing
   // filling the vector
   return toFill;
}
在本例中,每次通过循环时,
GetVector
都会分配一个新的
vector
,这可能是浪费,因为
vector
有一个可以在这样的循环中重用的容量。考虑一下改写:

void
GetVector(int someIndex, vector<BigData>& toFill)
{
   toFill.clear();
   // some processing
   // filling the vector
   return toFill;
}
// ...
vector<BigData> data;
while (I_need_to)
{
    GetVector(someIndex, data);
    process(data);
}
void
GetVector(int-someIndex、vector和toFill)
{
toFill.clear();
//一些加工
//填充向量
返乡;
}
// ...
矢量数据;
而(我需要)
{
GetVector(someIndex,data);
过程(数据);
}
在这次重写中,
data
每次通过循环时仍然会获得一个新值。但不同之处在于保存了上一个循环中的
capacity()
,并将其重新用于当前循环。如果此循环所需的
data.size()
小于上一个循环的
data.capacity()
,则当前循环不需要重新分配。减少对堆的访问是提高效率的关键。实际上,减少到堆的行程是移动语义的全部内容

我猜这就是视频中讨论的要点


我应该强调:如果工厂函数不打算在这样的循环中使用,或者如果工厂函数的返回类型不能利用以前的资源(如
capacity()
),那么使用inOut参数进行重写没有任何好处。

我无法理解Herb、Andrei或Scott的想法。(旁白:这些人——都很有才华——都与阿波罗太空计划(视频中的背景)毫无关系)。不过,我可以对右值引用/移动语义添加一些见解

如果您有纯工厂功能,如:

vector<BigData>
GetVector(int someIndex)
{
   vector<BigData> toFill;
   // some processing
   // filling the vector
   return toFill;
}
在本例中,每次通过循环时,
GetVector
都会分配一个新的
vector
,这可能是浪费,因为
vector
有一个可以在这样的循环中重用的容量。考虑一下改写:

void
GetVector(int someIndex, vector<BigData>& toFill)
{
   toFill.clear();
   // some processing
   // filling the vector
   return toFill;
}
// ...
vector<BigData> data;
while (I_need_to)
{
    GetVector(someIndex, data);
    process(data);
}
void
GetVector(int-someIndex、vector和toFill)
{
toFill.clear();
//一些加工
//填充向量
返乡;
}
// ...
矢量数据;
而(我需要)
{
GetVector(someIndex,data);
过程(数据);
}
在这次重写中,
data
每次通过循环时仍然会获得一个新值。但不同之处在于保存了上一个循环中的
capacity()
,并将其重新用于当前循环。如果此循环所需的
data.size()
小于上一个循环的
data.capacity()
,则当前循环不需要重新分配。减少对堆的访问是提高效率的关键。实际上,减少到堆的行程是移动语义的全部内容

我猜这就是视频中讨论的要点


我应该强调:如果工厂函数不打算在这样的循环中使用,或者如果工厂函数的返回类型不能利用以前的资源(如
capacity()
),那么使用inOut参数进行重写没有任何好处。

我无法理解Herb、Andrei或Scott的想法。(旁白:这些人——都很有才华——都与阿波罗太空计划(视频中的背景)毫无关系)。不过,我可以对右值引用/移动语义添加一些见解

如果你有一个纯工厂函数