3

我想做的是让我的班级在施工期间接受一个字符串。我读到这string_view是一个替代品,const string&所以我很自然地写了一个这样的构造函数。这允许我接受 c++ 和 c 字符串。

Url::Url(boost::string_view raw_url)
    : url_(static_cast<std::string>(raw_url)) {

这里可能存在的问题是,当传递一个右值时,会有一个不必要的副本而不是移动。是制作另一个构造函数的解决方案string&&吗?这里的最佳做法是什么?

4

1 回答 1

4

注意:我会考虑 写答案std::string_view,但boost::string_view应该是相似的。


我读到 string_view 是 const string& 的替代品

std::string_view了解最初添加的原因很有用。

有什么问题const string&

如果你传递一个std::string对象并且你没有得到任何东西,那肯定是有效的std::string_view。但是假设现在您正在传递一个char*包含一个大字符串的值。std::string在这种情况下,将创建一个临时对象(并char*复制该对象引用的整个字符串),以便函数接收std::string. 那是std::string_view发光的时候。如果您将 achar*或 a std::string(或任何可以转换为的东西std::string_view)传递给一个接受std::string_view(按值,不需要std::string_view通过引用接受 a )的函数,那么std::string_view创建的新对象非常便宜,因为它只是“一个视图”并且它不会复制底层字符串。


但你的情况不同。由于无论如何您都在复制字符串,因此您的函数应该只按值接受字符串并将字符串移动到函数内。诸如此类的东西

Url::Url(std::string raw_url)
    : url_(std::move(raw_url)) {

甚至还有一个整洁的警告告诉你这一点。

优点是,如果您的函数的用户传递了一个左值,您将制作一个副本(无论如何您都需要它)和一个移动,但是如果他们传递一个右值,那么就没有副本,只有一个移动。

于 2020-05-28T20:54:14.947 回答