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 个原因:

  1. 您只想读取权限。
  2. 可读性:用户很快就会明白 map 不会被修改。
  3. 使用 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 当然是一个副本。此外,在这种情况下,您的具有移动语义的版本将无法编译。

如果你真的想确保地图不被复制,你可以使用 &&,但这种情况很少见,而且在我看来,应该只用于不能复制的对象被复制(即流对象)。