C++ std::regex的不一致行为
我有以下问题:C++ std::regex的不一致行为,c++,boost,std,boost-filesystem,C++,Boost,Std,Boost Filesystem,我有以下问题: 如果传递boost::filesystem::path::string()vs将结果存储在中间字符串变量中,则std::regex的行为会有所不同。第一个将返回一个被截断的匹配项,该匹配项稍后不会被std::stoull接受(抛出无效的\u参数异常),而第二个将正常工作 请参阅以下命令以详细解释此问题: [nix shell:~]$ls-l foo 总数0 -rw-r--r--1胺用户0 2008年8月10日16:55 -rw-r--r--1胺用户0 Aug 10 15:47
- 如果传递
vs将结果存储在中间字符串变量中,则std::regex的行为会有所不同。第一个将返回一个被截断的匹配项,该匹配项稍后不会被boost::filesystem::path::string()
接受(抛出无效的\u参数异常),而第二个将正常工作std::stoull
[nix shell:~]$ls-l foo
总数0
-rw-r--r--1胺用户0 2008年8月10日16:55
-rw-r--r--1胺用户0 Aug 10 15:47 2530047398992289207
[nix外壳:~]$cat test-1.cpp
因此,我的问题是:
- 为什么直接使用
时会截断boost::filesystem::path::string()
的结果std::regex
- 假设match变量中的结果被截断了,那么为什么
会抛出异常呢std::stoull
- 您不幸落入了陷阱。在C++11中,调用的
std::regex_match
的重载是
template< class STraits, class SAlloc,
class Alloc, class CharT, class Traits >
bool regex_match( const std::basic_string<CharT,STraits,SAlloc>& s,
std::match_results<
typename std::basic_string<CharT,STraits,SAlloc>::const_iterator,
Alloc
>& m,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default );
因此,您无法再传递临时字符串
如果不能使用C++14,则需要确保没有将临时字符串传递给
std::regex\u match
您使用的是哪个版本的gcc?libstc++中std::regex的早期实现是buggy@AlanBirtles我使用的是gcc 7.3.0,我想创建一个由匹配函数返回的小助手结构,该函数将字符串和matcher对象存储在一起。有时它可能效率不高,但使用起来很简单,我可以传入一个临时字符串。不过,g++-o test1 test-1.cpp-lboost_filesystem-O0-g-std=c++14的结果似乎是一样的?这难道不应该吗?@AmineChikhaoui如果有什么问题的话,它应该无法在C++14中编译。@AmineChikhaoui它应该无法编译。如果不一致,则表示库不一致。原因是match_result对象只是将偏移量存储到字符串中,因此您需要使用字符串来查找实际字符串。
#include <iostream>
#include <regex>
#include <string>
#include <boost/filesystem.hpp>
int main() {
std::regex expression{R"(([0-9]+))"};
boost::filesystem::path cacheDir("/home/amine/foo");
for (const auto& entry : boost::filesystem::directory_iterator{cacheDir})
{
std::smatch match;
auto what = entry.path().filename().string();
auto result = std::regex_match(what, match, expression);
std::cout << "Result: " << result << std::endl
<< "Length: " << match[1].length() << std::endl
<< "Match: " << match[1] << std::endl
<< "Filename: " << entry.path().filename().string() << std::endl
<< std::endl;
std::stoull(match[1], 0);
}
return 0;
}
template< class STraits, class SAlloc,
class Alloc, class CharT, class Traits >
bool regex_match( const std::basic_string<CharT,STraits,SAlloc>& s,
std::match_results<
typename std::basic_string<CharT,STraits,SAlloc>::const_iterator,
Alloc
>& m,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default );
template< class STraits, class SAlloc,
class Alloc, class CharT, class Traits >
bool regex_match( const std::basic_string<CharT,STraits,SAlloc>&&,
std::match_results<
typename std::basic_string<CharT,STraits,SAlloc>::const_iterator,
Alloc
>&,
const std::basic_regex<CharT,Traits>&,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default ) = delete;