Jon*_*Mee 8 c++ regex assertion c++11 visual-studio-2013
我在Visual Studio 2013上,我看到了我认为的错误,我希望有人可以证实?
string foo{ "A\nB\rC\n\r" };
vector<string> bar;
for (sregex_iterator i(foo.cbegin(), foo.cend(), regex("(.*)[\n\r]{1,2}")); i != sregex_iterator(); ++i){
bar.push_back(i->operator[](1).str());
}
Run Code Online (Sandbox Code Playgroud)
此代码命中Visual Studio regex库中的Debug Assertion:
regex_iterator孤
如果我定义regex外部for-loop就可以了:
string foo{ "A\nB\rC\n\r" };
vector<string> bar;
regex bug("(.*)[\n\r]{1,2}");
for (sregex_iterator i(foo.cbegin(), foo.cend(), bug); i != sregex_iterator(); ++i){
bar.push_back(i->operator[](1).str());
}
Run Code Online (Sandbox Code Playgroud)
或者,这可以在转换中正常工作,如此问题所示:
string foo{ "A\nB\rC\n\r" };
vector<string> bar;
// This puts {"A", "B", "C"} into bar
transform(sregex_iterator(foo.cbegin(), foo.cend(), regex("(.*)[\n\r]{1,2}")), sregex_iterator(), back_inserter(bar), [](const smatch& i){ return i[1].str(); });
Run Code Online (Sandbox Code Playgroud)
有人可以证实这是一个错误吗?
Sha*_*our 10
在C++ 11你被允许结合临时regex到const regex &如果迭代使用临时的寿命之外,因为这将存储指向它可导致未定义的行为.这是规范中的缺陷,虽然Visual Studio通过调试断言捕获了它,但它并不是错误.
sregex_iterator i(foo.cbegin(), foo.cend(), regex("(.*)[\n\r]{1,2}"))
^^^^^
temporary
Run Code Online (Sandbox Code Playgroud)
以下删除的重载是在C++ 14中添加来防止这种情况,来自cppreference:
regex_iterator(BidirIt, BidirIt,
const regex_type&&,
std::regex_constants::match_flag_type =
std::regex_constants::match_default) = delete; (since C++14)
Run Code Online (Sandbox Code Playgroud)
它说:
不允许使用临时正则表达式调用重载2,因为返回的迭代器将立即失效.
所以这不是一个Visual Studio错误,因为它正在实现C++ 11标准,直到后来才通过缺陷报告解决.无论clang和gcc使用-std=c++14以上将产生你的第一个错误(见直播)和第三(见直播)的例子.Visual Studio仅开始支持VS 2015中的一些C++ 14 :
[...]并初步支持某些C++ 14功能.[...]
我们可以看到LWG缺陷2332:regex_iterator/regex_token_iterator应该禁止临时正则表达式处理:
用户可以写"for(sregex_iterator i(s.begin(),s.end(),regex("meow")),end; i!= end; ++ i)",将临时正则表达式绑定到const regex&存储指向它的指针.这将静默编译,在运行时触发未定义的行为.我们现在有了防止这种编译的技术,就像reference_wrapper拒绝绑定到temporaries一样.
正如TC指出你显示的最后一个例子实际上是好的,即使你绑定一个临时的,它的生命周期延伸到表达式的结尾.
| 归档时间: |
|
| 查看次数: |
514 次 |
| 最近记录: |