代码之家  ›  专栏  ›  技术社区  ›  Alberto Miola user831258

在函数重载中将右值引用实现为参数

  •  5
  • Alberto Miola user831258  · 技术社区  · 6 年前

    我已经问过关于代码审查和软件工程的问题,但是这个话题不适合这个网站,所以我在这里问,希望这不是基于意见的。我是一个“老学校”C++开发人员(我已经在C++ 2003停止了),但是现在我已经读了一些关于现代C++ 11/17的书,我正在重写我的一些库。

    我做的第一件事是在需要的地方添加移动构造函数/赋值操作符(=已经有析构函数的类+复制构造函数和复制赋值)。基本上我用的是 五法则 .

    我的大多数函数的声明如下

    func(const std::string& s);
    

    这是传递引用以避免复制的常见方法。顺便说一下,还有新的移动语义,还有一些我在我的书/网上找不到的东西。此代码:

    void fun(std::string& x) {
        x.append(" world"); 
        std::cout << x;
    }
    
    int main()
    {
        std::string s{"Hello "};
        fun(s);
    }
    

    也可以写为:

    void fun(std::string&& x) {
        x.append(" world"); 
        std::cout << x;
    }
    
    int main()
    {
        std::string s{"Hello "};
        fun(std::move(s));
        //or fun("Hello ");
        // or fun(std::string {"Hello" });
    }
    

    我的问题是:什么时候应该声明接受一个参数中心作为右值引用的函数?


    我了解构造函数和赋值运算符的语义用法,但实际上不了解函数的语义用法。在上面的例子中(第一个函数),我有一个 std::string& x 不能称为 fun("Hello "); 当然,因为我应该把这个类型 const std::string& x . 但现在常量不允许我更改字符串!

    是的,我可以使用const cast,但我很少进行强制转换(如果是这样的话,它们是动态强制转换)。它的作用是我避免复制,我不必做类似的事情

    std::string x = "...";
    fun(x); //void fun(std::string& x) {}
    

    我可以分配将要移动的临时值。如果可能,我应该用右值引用声明函数吗?

    我有一个图书馆,我用现代C++ 17改写,我的功能有:

    //only const-ref
    Type1 func(const type2& x);
    Type3 function(const type4& x);
    

    我在问是否值得把它们全部改写为

    //const-ref AND rvalue reference
    Type1 func(const type2& x);
    Type3 function(const type4& x);
    
    Type1 func(type2&& x);
    Type3 function(type4&& x);
    

    我不想创建太多的重载,这些重载可能是无用的,但是如果我的库的用户想要使用移动操作,我应该创建&param类型。当然,我并不是为基元类型(int、double、char…)这样做,而是为容器或类。你有什么建议?

    我不确定后一种方案(两种版本都有)是否有用。

    3 回复  |  直到 6 年前
        1
  •  4
  •   lubgr    6 年前

    • std::string_view const std::string&
    • const T& T&& T void fun void fun(std::string&&)
    • std::vector::push_back
    • std::forward
        2
  •  2
  •   hoffmale    6 年前

    • std::vector

    T&& T

        3
  •  1
  •   SergeyA    6 年前

    std::unique_prt