为什么c ++ regex_match函数需要在函数外定义搜索字符串?

时间:2014-12-09 23:48:40

标签: c++ regex visual-studio

我正在使用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

这对我没有意义。任何人都可以解释为什么会这样吗?

1 个答案:

答案 0 :(得分:10)

原因是get()返回一个临时字符串,因此匹配结果包含一个不再存在的对象的迭代器,并且尝试使用它们是未定义的行为。 Visual Studio C ++库中的调试断言会发现此问题并中止您的程序。

最初C ++ 11确实允许你尝试做什么,但是因为它是如此危险,所以通过添加std::regex_match的删除重载来阻止它在尝试从临时获取匹配结果时被使用字符串,请参阅LWG DR 2329。这意味着您的程序不应该在C ++ 14中编译(或者在C ++ 11模式下实现DR的编译器中编译)。 GCC尚未实施此更改,我将解决此问题。