【问题标题】:Returning objects constructed in lambda in transform在转换中返回在 lambda 中构造的对象
【发布时间】:2021-10-04 01:37:59
【问题描述】:

以下函数做了一些与我想要的不同的事情,即返回匹配项。如果我在vector<string>{"a b", "cd ef"} 上调用它,输出是

cd 
cd ef

而不是

a b
cd ef

为什么?

#include <regex>
using namespace std;

void f(const vector<string>& v) {
  vector<smatch> P{};
  transform(begin(v), end(), back_inserter(P), [](auto s){
    auto m = *new smatch;
    regex_match(s, m, regex{"(\\S*) (\\S*) ?(.*)"});
    return m;
  });
  for (auto s: P) cout << s[0] << endl; // debug output
}

如果我尝试不使用newsmatch m{};,情况相同。我相信我不应该这样做,因为 smatch 被分配在堆栈上,并在 lambda 函数返回时失效。 (我什至试过smatch m;,但这应该会创建一个未初始化的变量。奇怪的是,它没有运行时错误,给出相同的错误结果。)以下甚至没有编译,给出一个我不明白的错误:

#include <regex>
using namespace std;

void f(const vector<string>& v) {
  vector<smatch> P{};
  transform(begin(v), end(), back_inserter(P), [](auto s){
    auto m = new smatch;
    regex_match(s, m, regex{"(\\S*) (\\S*) ?(.*)"});
    cout << (*m)[0] << endl;
    return m;
  });
  for (auto s: P) cout << (*s)[0] << endl;
}

【问题讨论】:

  • 另外:vector&lt;smatch&gt; P{};smatch m{}; 中的{} 是否必要?我是否正确,否则变量未初始化并可能导致运行时错误?
  • vector&lt;smatch&gt; P{};smatch m{}; 与此处的 vector&lt;smatch&gt; P;smatch m; 相同。

标签: c++ object lambda return-value transformation


【解决方案1】:

对于std::match_results

因为std::match_results 拥有std::sub_matches,每个都是匹配的原始字符序列的一对迭代器,如果原始字符序列被破坏或迭代器无效,检查std::match_results 是未定义的行为其他原因。

lambda 的参数s 是传值的,退出后会被销毁。您可以将其更改为传递引用:

void f(const vector<string>& v) {
  vector<smatch> P;
  transform(begin(v), end(v), back_inserter(P), [](auto& s){
    //                                                 ^
    smatch m;
    regex_match(s, m, regex{"(\\S*) (\\S*) ?(.*)"});
    return m;
  });
  for (auto s: P) cout << s[0] << endl; // debug output
}

【讨论】:

  • 但是m 不会在 lambda 完成执行时获得自动生命周期及其析构函数吗?
  • @ByteEater 是的。但它会被复制为 lambda 的返回值,然后复制到向量 P
  • 更准确地说,它会被移动而不是复制吗? match_results,其中smatch 是一个特化,有一个移动构造函数。另外(在您编辑之后),为了更好地理解,我想问一下:构造函数会被调用两次吗?
  • @ByteEater 是的,它会被移动两次。一种用于return,一种用于将push_back编入vector
猜你喜欢
  • 1970-01-01
  • 2012-08-09
  • 2019-09-12
  • 2022-01-20
  • 1970-01-01
  • 2018-04-03
  • 2011-12-29
  • 2022-07-07
  • 2017-02-22
相关资源
最近更新 更多