使用http://en.cppreference.com/w/cpp/string/basic_string_view作为参考,我认为没有办法更优雅地做到这一点:
std::string s = "hello world!";
std::string_view v = s;
v = v.substr(6, 5); // "world"
更糟糕的是,幼稚的方法是一个陷阱,并留下v
了对临时对象的悬挂:
std::string s = "hello world!";
std::string_view v(s.substr(6, 5)); // OOPS!
我似乎记得类似的东西,可能在标准库中添加了一个将子字符串作为视图返回的内容:
auto v(s.substr_view(6, 5));
我可以想到以下解决方法:
std::string_view(s).substr(6, 5);
std::string_view(s.data()+6, 5);
// or even "worse":
std::string_view(s).remove_prefix(6).remove_suffix(1);
坦白说,我认为这些都不是很好。现在,我能想到的最好的事情就是使用别名来使事情变得不再那么冗长。
using sv = std::string_view;
sv(s).substr(6, 5);
有自由功能路线,但是除非您也提供过载,std::string
否则这是一个蛇坑。
#include <string>
#include <string_view>
std::string_view sub_string(
std::string_view s,
std::size_t p,
std::size_t n = std::string_view::npos)
{
return s.substr(p, n);
}
int main()
{
using namespace std::literals;
auto source = "foobar"s;
// this is fine and elegant...
auto bar = sub_string(source, 3);
// but uh-oh...
bar = sub_string("foobar"s, 3);
}
恕我直言,string_view的整个设计是一个恐怖的表演,它将把我们带回到一个充满节节和生气客户的世界。
甚至添加超载std::string
也是恐怖的表演。看看您是否能发现微妙的段错误定时炸弹...
#include <string>
#include <string_view>
std::string_view sub_string(std::string_view s,
std::size_t p,
std::size_t n = std::string_view::npos)
{
return s.substr(p, n);
}
std::string sub_string(std::string&& s,
std::size_t p,
std::size_t n = std::string::npos)
{
return s.substr(p, n);
}
std::string sub_string(std::string const& s,
std::size_t p,
std::size_t n = std::string::npos)
{
return s.substr(p, n);
}
int main()
{
using namespace std::literals;
auto source = "foobar"s;
auto bar = sub_string(std::string_view(source), 3);
// but uh-oh...
bar = sub_string("foobar"s, 3);
}
编译器在这里没有发现任何警告。我敢肯定,代码审查也不会。
我已经说过了,再说一遍,以防c ++委员会上的任何人在看,允许从std::string
到的隐式转换std::string_view
是一个可怕的错误,只会使c ++蒙羞。
在cpporg留言板上提出了这个(对我来说)相当令人震惊的string_view属性后,我的顾虑便变得冷漠。
该小组的建议的共识是,std::string_view
绝不能从函数中返回它,这意味着我在上面的第一个提议是错误的形式。
当然,如果偶然发生(例如通过模板扩展),则没有编译器帮助来捕获时间。
因此,std::string_view
应格外小心,因为从内存管理的角度来看,它等效于指向另一个对象状态的可复制指针,该对象可能不再存在。但是,它在所有其他方面的外观和行为都类似于值类型。
因此,代码如下:
auto s = get_something().get_suffix();
get_suffix()
返回std::string
(按值或引用)时是安全的
但是如果将get_suffix()重构为返回a,则为UB std::string_view
。
在我的拙劣观点中,这意味着auto
如果将其调用的库重构为std::string_view
代替的返回值,则使用返回的字符串存储的任何用户代码都将中断std::string const&
。
因此,从现在开始,至少对于我来说,“几乎总是自动的”必须变成“几乎总是自动的,除非是字符串”。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句