假设我们在一个类中有一个简单的getter方法,该方法返回对const
成员的std::string
引用:
const std::string& getString() const noexcept { return someString; }
随着C ++ 17中std::string_view
的到来,我想知道它是否具有代替编写此代码的优势:
const std::string_view getString() const noexcept { return someString; }
一种方法比另一种方法有优点/缺点吗?显然(如果我错了,请纠正我),两种解决方案肯定会比这个更好:
const char* getString() const noexcept { return someString.c_str(); }
我已经看到了this个相关问题,但我要问的问题略有不同。
答案 0 :(得分:14)
是的,您应该写:
const std::string& getString() const noexcept { return someString; }
代替(请注意:不要使用const
,因为从不返回const
值):
std::string_view getString() const noexcept { return someString; }
原因是-您已经有一个string
。因此,您不必为此付出任何额外的费用即可获得string
。 string
与任意string_view
有一个显着的语义差异:保证为以空值结尾的。我们知道这一点。也许某些下游用户需要依赖该信息。如果他们需要空终止(例如,他们需要传递给需要它的C API),而您给出了string_view
,则他们必须从中得出string
他们自己。您什么都不做,却有可能使下游用户做更多的工作。
但是,如果您改为使用vector<char>
...那么我建议您返回span<char const>
或类似的值。由于没有语义上的差异,您只是提供一个视图。
还有什么的单独论点:
auto x = obj.getString();
应该做。这要么获取string
的副本(价格昂贵,但安全),要么对其进行有效引用(价格低廉,但可能会悬挂)。但是它看起来并不完全像是参考,而是看起来像一个值。一般而言,这是一个广泛的引用语义类型问题(诸如reference_wrapper
,string_view
,span
,tuple<T&...>
,optional<T&>
等)。 )。
对于这种情况,我没有答案,但这是需要注意的事情。