regex_token_iterator尝试引用已删除的函数

时间:2018-12-02 16:39:26

标签: c++ regex

我正在尝试使用C ++中的正则表达式拆分字符串。这是最低再现:

#include <string>
#include <regex>

int main()
{
  std::string str("abc");
  std::string regex("b");
  std::regex_token_iterator<std::string::const_iterator> a(str.begin(), str.end(), std::regex(regex), -1);
}

该程序给我一个编译错误:试图引用已删除的函数

error C2280: 'std::regex_token_iterator<std::_String_const_iterator<std::_String_val<std::_Simple_types<_Ty>>>,char,std::regex_traits<char>>::regex_token_iterator(_BidIt,_BidIt,const std::basic_regex<char,std::regex_traits<char>> &&,int,std::regex_constants::match_flag_type)': attempting to reference a deleted function

但是我觉得我已经正确设置了。为什么会出现此错误,需要进行哪些更改才能进行编译?

我以this gist为例,但是我也无法编译它。

我正在使用Microsoft Visual Studio 2017 15.8.4进行构建

1 个答案:

答案 0 :(得分:2)

regex作为临时对象的构造函数被删除,因为 迭代器不会复制regex,但会保留对此对象的引用。 删除此功能是为了防止将临时变量传递给迭代器。 如果将临时对象传递给迭代器,则会得到悬挂的引用。

根据reference

regex_token_iterator( BidirectionalIterator a, BidirectionalIterator b,
                      const regex_type&& re,
                      int submatch = 0,
                      std::regex_constants::match_flag_type m =
                          std::regex_constants::match_default ) = delete;

所以您需要做的是将正则表达式创建为 L值对象:

  std::string str("abc");
  std::string regex("b");
  std::regex r(regex);
  std::regex_token_iterator<std::string::const_iterator> a(
       str.begin(), str.end(), r, -1);

关于您发布的链接,自C ++ 14起引入了引用R值的已删除重载,在C ++ 11中存在重载const regex_type& re的重载-因此可以将regex的临时对象设为传递给迭代器的ctor,但会导致不确定的行为