在 C++11 中你可以绑定一个临时的regex
to const regex &
如果迭代器在临时生命周期之外使用,这可能会导致未定义的行为,因为它将存储指向它的指针。这是规范中的缺陷,并不是错误,尽管 Visual Studio 通过调试断言捕获了此问题。
sregex_iterator i(foo.cbegin(), foo.cend(), regex("(.*)[\n\r]{1,2}"))
^^^^^
temporary
C++14 中添加了以下删除的重载以防止这种情况,从参考参数 http://en.cppreference.com/w/cpp/regex/regex_iterator/regex_iterator:
regex_iterator(BidirIt, BidirIt,
const regex_type&&,
std::regex_constants::match_flag_type =
std::regex_constants::match_default) = delete; (since C++14)
它说:
不允许使用临时正则表达式调用重载 2,
因为返回的迭代器将立即失效。
所以这不是一个Visual Studio
bug,因为它正在实现 C++11 标准,并且直到后来才通过缺陷报告解决这个问题。两个都clang
and gcc
using -std=c++14
或更大的值会导致你的第一个错误(现场观看 http://melpon.org/wandbox/permlink/gepU41fsWrHBgHm2)和第三个(现场观看 http://melpon.org/wandbox/permlink/a8WYGC64U2uXr9vX) 例子。 Visual Studio 仅开始支持部分 C++14VS 2015 https://www.visualstudio.com/en-us/news/vs2015-preview-vs.aspx:
[...]以及对某些 C++14 功能的初步支持。[...]
我们可以看到LWG 缺陷 2332:regex_iterator/regex_token_iterator 应禁止临时正则表达式 http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2332处理这个:
用户可以编写“for(sregex_iterator i(s.begin(), s.end(),
正则表达式(“喵”)),结束;我!=结束; ++i)",将临时正则表达式绑定到
const regex& 并存储指向它的指针。这将静默编译,
在运行时触发未定义的行为。我们现在有技术
以防止编译,就像 Reference_wrapper 拒绝这样做一样
绑定到临时对象。
作为 T.C.指出您显示的最后一个示例实际上是可以的,即使您绑定的是临时变量,它的生命周期也会延伸到表达式的末尾。