C++ 使用移动语义将参数传递给另一个函数
C++ using move semantics to pass argument to another function
我有一个接受 2 个参数的函数,但其中一个(地图容器)被传递给另一个函数:
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
}
main.cpp 中的某处:
std::map<std::string, int> map1{ {"Hello", 10}, {"Hello2", 20}, {"Hello3", 30} };
myFunc(map1, 20);
我的问题是:
移动语义是优化这段代码(使用移动将一个参数传递给另一个函数)的好方法吗:
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...
}
在这种情况下,我不喜欢使用通用引用(使用模板)和 std::forward,因为总是使用这种类型的地图调用此函数,我希望代码尽可能简单。
internalFunc 总是被这个特定的函数 myFunc 调用。
移动语义是优化此类功能的好方法吗?我知道使用移动语义进行优化取决于移动的对象类型,但让我们坚持上面使用标准地图容器的示例。
谢谢
如果您需要修改 map
或函数出于某种原因需要取得 map
的所有权(也许后者更容易理解,如果函数是 class 成员,例如 setter 或构造函数)。
您应该使用 const std::map<std::string, int>&
主要有 3 个原因:
- 您只想读取权限。
- 可读性:用户很快就会明白
map
不会被修改。
- 使用
move
语义不会获得更好的结果。
移动语义注意事项
如果您使用移动语义,您的函数的参数不一定需要双 &&
。通常,最好省略它们(完美转发和不可复制的对象(如流对象)除外)。 &&
要求传递的参数为 rvalues
。但是,省略 &&
确实 而不是 意味着您不能将参数作为 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...
}
上面代码中的参数 myMap
如果您将它们作为 rvalues
:
传递,则 不会被复制
int main()
{
myFunc({ {"Hello", 10}, {"Hello2", 20}, {"Hello3", 30} }, 20);
return 0;
}
此外,您现在可以通过传递 lvalues
使用相同的代码,就像您在问题的 main
函数中所做的那样 (myFunc(map1, 20);
)。 myFunc
中的参数 myMap
当然是一个副本。此外,在这种情况下,您的具有移动语义的版本将无法编译。
如果你真的想确保地图不被复制,你可以使用 &&
,但这种情况很少见,而且在我看来,应该只用于不能复制的对象被复制(即流对象)。
我有一个接受 2 个参数的函数,但其中一个(地图容器)被传递给另一个函数:
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
}
main.cpp 中的某处:
std::map<std::string, int> map1{ {"Hello", 10}, {"Hello2", 20}, {"Hello3", 30} };
myFunc(map1, 20);
我的问题是:
移动语义是优化这段代码(使用移动将一个参数传递给另一个函数)的好方法吗:
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...
}
在这种情况下,我不喜欢使用通用引用(使用模板)和 std::forward,因为总是使用这种类型的地图调用此函数,我希望代码尽可能简单。
internalFunc 总是被这个特定的函数 myFunc 调用。
移动语义是优化此类功能的好方法吗?我知道使用移动语义进行优化取决于移动的对象类型,但让我们坚持上面使用标准地图容器的示例。
谢谢
如果您需要修改 map
或函数出于某种原因需要取得 map
的所有权(也许后者更容易理解,如果函数是 class 成员,例如 setter 或构造函数)。
您应该使用 const std::map<std::string, int>&
主要有 3 个原因:
- 您只想读取权限。
- 可读性:用户很快就会明白
map
不会被修改。 - 使用
move
语义不会获得更好的结果。
移动语义注意事项
如果您使用移动语义,您的函数的参数不一定需要双 &&
。通常,最好省略它们(完美转发和不可复制的对象(如流对象)除外)。 &&
要求传递的参数为 rvalues
。但是,省略 &&
确实 而不是 意味着您不能将参数作为 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...
}
上面代码中的参数 myMap
如果您将它们作为 rvalues
:
int main()
{
myFunc({ {"Hello", 10}, {"Hello2", 20}, {"Hello3", 30} }, 20);
return 0;
}
此外,您现在可以通过传递 lvalues
使用相同的代码,就像您在问题的 main
函数中所做的那样 (myFunc(map1, 20);
)。 myFunc
中的参数 myMap
当然是一个副本。此外,在这种情况下,您的具有移动语义的版本将无法编译。
如果你真的想确保地图不被复制,你可以使用 &&
,但这种情况很少见,而且在我看来,应该只用于不能复制的对象被复制(即流对象)。