我正在使用Visual Studio 2013进行开发,它使用的是Microsoft的c ++编译工具v12 以下代码执行正常,打印" foo"到控制台:
#include <regex>
#include <iostream>
#include <string>
std::string get() {
return std::string("foo bar");
}
int main() {
std::smatch matches;
std::string s = get();
std::regex_match(s, matches, std::regex("^(foo).*"));
std::cout << matches[1] << std::endl;
}
// Works as expected.
相同的代码,字符串&#34; s&#34;取代&#34; get()&#34;函数,抛出一个&#34;字符串迭代器不兼容&#34;运行时出错:
#include <regex>
#include <iostream>
#include <string>
std::string get() {
return std::string("foo bar");
}
int main() {
std::smatch matches;
std::regex_match(get(), matches, std::regex("^(foo).*"));
std::cout << matches[1] << std::endl;
}
// Debug Assertion Failed!
// Expression: string iterators incompatible
这对我没有意义。任何人都可以解释为什么会这样吗?
答案 0 :(得分:10)
原因是get()
返回一个临时字符串,因此匹配结果包含一个不再存在的对象的迭代器,并且尝试使用它们是未定义的行为。 Visual Studio C ++库中的调试断言会发现此问题并中止您的程序。
最初C ++ 11确实允许你尝试做什么,但是因为它是如此危险,所以通过添加std::regex_match
的删除重载来阻止它在尝试从临时获取匹配结果时被使用字符串,请参阅LWG DR 2329。这意味着您的程序不应该在C ++ 14中编译(或者在C ++ 11模式下实现DR的编译器中编译)。 GCC尚未实施此更改,我将解决此问题。