string.assign(string.data(),5)是定义明确的还是UB?

问题描述 投票:11回答:1

一个同事想写这个:

std::string_view strip_whitespace(std::string_view sv);

std::string line = "hello  ";
line = strip_whitespace(line);

[我说返回string_view使我不安先验,此外,这里的别名在我看来像UB。

我可以肯定地说,在这种情况下,line = strip_whitespace(line)等于line = std::string_view(line.data(), 5)。我相信会调用string::operator=(const T&) [with T=string_view],它被定义为等效于string::operator=(const T&) [with T=string_view],它被定义为等效于line.assign(const T&) [with T=string_view],被定义为执行此操作:

line.assign(const T&) [with T=string_view]

但是这并不能说明出现别名时会发生什么。

我昨天在cpplang Slack上问了这个问题,得到了不同的答案。在这里寻找超级权威的答案,和/或对真实库供应商实施的经验分析。


line.assign(line.data(), 5)line.assign(line.data(), 5)Preconditions: [s, s + n) is a valid range. Effects: Replaces the string controlled by *this with a copy of the range [s, s + n). Returns: *this. I wrote test casesstring::assign的[vector::assign

  • Libc ++使所有这些测试用例都起作用。
  • Libstdc ++使它们都可以工作,但deque::assign除外,这是段错误。
  • 我不知道MSVC的库。

libstdc ++中的段错误使我希望它是UB;但我也看到libc ++和libstdc ++都将付出巨大的努力,至少在通常情况下才能使此工作正常进行。

c++ stl undefined-behavior
1个回答
8
投票

[除非有几个例外,但您不是一个例外,请在指向其元素的字符串list::assign [...]指针[...]上调用非常量成员函数(即forward_list::assign)。这违反了forward_list上的assign,即invalidates是有效范围,因此这是未定义的行为。

请注意,precondition的语言专门用于使自指派成为无人值守。

© www.soinside.com 2019 - 2024. All rights reserved.