C++ C++;使用移动语义将参数传递给另一个函数
我的函数有两个参数,但其中一个(映射容器)被传递给另一个函数:C++ C++;使用移动语义将参数传递给另一个函数,c++,pass-by-reference,move-semantics,C++,Pass By Reference,Move Semantics,我的函数有两个参数,但其中一个(映射容器)被传递给另一个函数: void myFunc(const std::map<std::string, int> &myMap, int num) { int x = internalFunc(myMap); // do some stuff... } int internalFunc(const std::map<std::string, int> &myMap) { // return
void myFunc(const std::map<std::string, int> &myMap, int num) {
int x = internalFunc(myMap);
// do some stuff...
}
int internalFunc(const std::map<std::string, int> &myMap) {
// return some map statistics
}
void myFunc(const std::map&myMap,int num){
int x=内部函数(myMap);
//做些事情。。。
}
int internalFunc(const std::map和myMap){
//返回一些地图统计信息
}
main.cpp中的某个地方:
std::map<std::string, int> map1{ {"Hello", 10}, {"Hello2", 20}, {"Hello3", 30} };
myFunc(map1, 20);
地图地图1{{“你好”,10},{“你好”,20},{“你好”,30};
myFunc(map1,20);
我的问题是:
move语义是优化这段代码(使用move将一个参数传递给另一个函数)的好方法吗
int internalFunc(std::map<std::string, int> &&myMap) {
// now gets rvalue reference
// return some map statistics
}
void myFunc(std::map<std::string, int> myMap, int num) {
int x = internalFunc(std::move(myMap));
// do some stuff...
}
intinternalfunc(std::map&&myMap){
//现在获取右值引用
//返回一些地图统计信息
}
void myFunc(std::map myMap,int num){
intx=internalFunc(std::move(myMap));
//做些事情。。。
}
在这种情况下,我不喜欢使用通用引用(使用模板)和std::forward,因为此函数总是使用这种类型的映射调用,我更喜欢使代码尽可能简单
internalFunc始终由此特定函数myFunc调用
移动语义是优化这类函数的好方法吗?我知道使用移动语义进行优化取决于移动的对象类型,但让我们继续使用上面的标准贴图容器示例
谢谢如果您需要修改
映射
,或者如果函数出于某种原因需要拥有映射
(如果函数是类成员,例如setter或构造函数,后者可能更容易理解),则移动语义非常有用
您应该使用const std::map&
有三个主要原因:
地图
不会被修改move
语义不会得到更好的结果&&
。通常,最好省略它们(除了完美转发和不可复制的对象,如流对象)。&&
要求传递的参数为rvalues
。但是,省略&&
并不意味着不能将参数作为右值传递。让我们通过一个例子来了解这一点:
int internalFunc(std::map<std::string, int> myMap)
{
/* ... */
return 1; // or whatever
}
void myFunc(std::map<std::string, int> myMap, int num)
{
int x = internalFunc(std::move(myMap));
// do some stuff...
}
此外,您现在可以通过传递lvalues
来使用相同的代码,就像您在问题的main
函数中所做的那样(myFunc(map1,20);
)。myFunc
中的参数myMap
当然是一个副本。此外,在这种情况下,具有移动语义的版本将无法编译
如果你真的想确保地图不会被复制,你可以使用&&
,但这是相当罕见的,而且在我看来,应该只用于无法复制的对象(即流对象)。如果myFunc
或internalFunc
复制地图(或其中的一些字符串),而map1
在传递给myFunc
后不使用,则移动可能有用。move语义是优化这段代码(使用move将一个参数传递给另一个函数)的好方法吗?比如:“等等,你已经改变了代码的本质。在第一个示例中,需要一个常量&
。在第二种情况下,myFunc
按值获取参数,这需要从调用方的数据进行复制/移动。现在这是一个完全不同的函数。@HolyBlackCat,此函数调用后不使用map1。Nicol,是的,这是真的,在我的项目中,这个函数现在和常量引用一起工作,它不工作;不要改变地图的结构。然而,我想知道这是否会很慢,因为myFunc不使用map,只是将它传递给下一个函数。PS:在项目中,real map对象包含数百条记录,上面的示例被简化了。@Rafal Ok,但您是否在这些函数中复制了地图中的任何内容?(复制int
s不算)不,我只是做一些统计计算,不进一步传递任何地图元素或使用它,只使用只读用法。Thanx@mfnx,以获得精确答案。我想指出:>>如果将上述代码中的参数myMap作为右值传递,则不会复制它们:。。。注意:由于C++11中引入了移动语义,这是正确的。但是,在C++编译器(C++ 03和以下)的早期标准中,也会有一个拷贝。我希望我没有弄错。@SoldOut这个问题是关于移动语义的。不需要提及早期的标准。我理解-你的回答很好,它帮助了我。我只是提供这些信息来帮助其他人(年轻人)认识到这一局限性,因为他们处理的是遗留代码和编译器。我希望这将是更多的帮助,而不是混乱:)
int main()
{
myFunc({ {"Hello", 10}, {"Hello2", 20}, {"Hello3", 30} }, 20);
return 0;
}