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;
    }