C++ 使用移动语义将参数传递给另一个函数

Raf*_*fal 2 c++ pass-by-reference move-semantics

我有一个需要 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
}
Run Code Online (Sandbox Code Playgroud)

main.cpp 中的某处:

std::map<std::string, int> map1{ {"Hello", 10}, {"Hello2", 20}, {"Hello3", 30} };
myFunc(map1, 20);
Run Code Online (Sandbox Code Playgroud)

我的问题是:

移动语义是优化这段代码(使用移动将一个参数传递给另一个函数)的好方法,如下所示:

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...
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我不喜欢使用通用引用(使用模板)和 std::forward,因为总是使用这种类型的映射调用此函数,并且我更喜欢使代码尽可能简单。

InternalFunc 始终由这一特定函数 myFunc 调用。

移动语义是优化此类功能的好方法吗?我知道使用移动语义进行优化取决于移动的对象类型,但让我们继续使用上面的标准地图容器示例。

谢谢

MFn*_*Fnx 5

如果您需要修改map或函数出于某种原因需要获得 的所有权map(如果函数是类成员,例如 setter 或构造函数,则后者可能更容易理解),则移动语义很有用。

您应该使用的const std::map<std::string, int>&主要原因有 3 个:

  1. 您只需要读取权限。
  2. 可读性:用户很快就会明白不会map被修改。
  3. 使用语义你不会得到更好的结果move

关于移动语义的注释

如果您使用移动语义,则函数的参数不一定需要 double &&。一般来说,最好省略它们(完美转发和不可复制的对象(如流对象)除外)。要求&&传递的参数为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...
}
Run Code Online (Sandbox Code Playgroud)

如果将myMap上述代码中的参数传递rvalues为:

int main()
{
    myFunc({ {"Hello", 10}, {"Hello2", 20}, {"Hello3", 30} }, 20);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

此外,您现在可以通过传递 来使用相同的代码lvalues,就像在main问题 ( myFunc(map1, 20);) 的函数中所做的那样。myMap当然,其中的参数myFunc是副本。此外,在这种情况下,具有移动语义的版本将无法编译。

如果您确实想确保地图不被复制,您可以使用&&,但这种情况相当罕见,并且在我看来,应该仅用于无法复制的对象(即流对象)。