gpt4 book ai didi

c++ - 将右值引用实现为函数重载中的参数

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:18:22 25 4
gpt4 key购买 nike

我已经询问过有关代码审查和软件工程的问题,但该主题不适合该网站,所以我在这里提问,希望这不是基于意见的。我是一名“守旧派”的 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 不允许我更改字符串!

是的,我可以使用 const 强制转换,但我很少使用强制转换(即使是这样,它们也是动态强制转换)。 && 的强大之处在于我避免了复制,我不必做类似的事情

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

我不想创建太多可能无用的重载,但如果我的库的用户想要使用移动操作,我应该创建 && 参数类型。当然,我这样做不是针对原始类型(int、double、char...),而是针对容器或类。你有什么建议?

我不确定后一种情况(两个版本)是否有用。

最佳答案

让我评论一下您的问题和示例中的四种情况。

    具有按值传递的
  • std::string_view 应该替换 const std::string& 参数,并且只要您可以保证安全使用的必要先决条件std::string_view(生命周期,pointee 不变),它是开始现代化您的函数签名的好选择。
  • const T&T&&(其中 T 不受模板类型推导的约束)与已知使用场景。附加到给定的可修改字符串的 void fun 函数只有在调用代码不需要之后的结果时才会作为 void fun(std::string&&) 有意义电话。在这种情况下,右值引用签名很好地记录了这种期望,并且是要走的路。但根据我的经验,这些情况很少见。
  • const T&T&&(同样,没有类型推导)在未知的使用场景下。 std::vector::push_back 是一个很好的引用,它为右值和左值引用都重载了。与移动构造 a T 相比,push_back 操作被认为是廉价的,这就是重载有意义的原因。当假设一个函数比这样的移动构造更昂贵时,按值传递参数是一种有意义的简化(另请参阅 EMC++ 中的第 41 项)。
  • const T&T&& 当发生类型推导时。在这里,尽可能将通用引用与 std::forward 一起使用,并且参数不能是 const 限定的。如果它们未在函数体中修改,请使用 const T&

关于c++ - 将右值引用实现为函数重载中的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51253572/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com