Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

regex - Why does the c++ regex_match function require the search string to be defined outside of the function?

I am using Visual Studio 2013 for development, which uses v12 of Microsoft's c++ compiler tools.
The following code executes fine, printing "foo" to the console:

#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.

The same code, with the string "s" substituted for the "get()" function, throws a "string iterators incompatible" error at runtime:

#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

This makes no sense to me. Can anyone explain why this happens?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The reason is that get() returns a temporary string, so the match results contains iterators into an object that no longer exists, and trying to use them is undefined behaviour. The debugging assertions in the Visual Studio C++ library notice this problem and abort your program.

Originally C++11 did allow what you're trying to do, but because it is so dangerous it was prevented by adding a deleted overload of std::regex_match which gets used when trying to get match results from a temporary string, see LWG DR 2329. That means your program should not compile in C++14 (or in compilers that implement the DR in C++11 mode too). GCC does not yet implement the change yet, I'll fix that.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...