【问题标题】:It is safe to use constructors in function parameters in C++?在 C++ 的函数参数中使用构造函数是否安全?
【发布时间】:2012-02-01 10:25:27
【问题描述】:

此 C++ 代码在 Visual Studio 2010 中失败:


const sregex_iterator end;
for (sregex_iterator match(origString.begin(), origString.end(), regex(regExPattern)); match != end; ++match)
{
    useMatch(*match);
}

在第一个循环之后,在第一个迭代器增量 (operator++) 中,调试器失败,表明 regex_iterator 是“孤立的”。

我注意到了可疑的正则表达式构造函数(我从某处复制了片段)并尝试了这个:


const sregex_iterator end;
regex regexObj(regExPattern);
for (sregex_iterator match(origString.begin(), origString.end(), regexObj); match != end; ++match)
{
    useMatch(*match);
}

效果很好。

但是,为什么第一次尝试失败了?我想它必须与for 范围或内联构造函数以及迭代器构造函数中的正则表达式参数是一个引用的事实......

但是,正如我前段时间在stackoverflow中阅读的,我只记得我理解的东西,我想知道在C++中使用构造函数作为函数参数是否安全(当然不使用new )。

【问题讨论】:

  • 您没有将const sregex_iterator end 初始化为任何内容是否正确?
  • @Chowlett:是的,这是创建“结束标记”迭代器的(不直观的)方法。

标签: c++ visual-studio-2010 std tr1


【解决方案1】:

我认为在第一种情况下,正则表达式是作为临时对象创建的,并且会在匹配初始化后立即销毁。它需要有一个贯穿整个循环的生命周期。

【讨论】:

  • +1:看起来很可能是初始化后正则表达式模式被破坏(超出范围)。
  • 那么,如果你在方法参数中调用构造函数,它只有那个调用的范围?这只有在方法复制参数(或按值传递)时才有效,不是吗?而且,为什么第一个循环有效?它只在 operator++ 中失败
  • 还有一件事:如果你是对的(我认为你是对的),那么这个页面中的示例是错误的,不是吗? en.cppreference.com/w/cpp/regex/regex_iterator
  • @JuanCalero:如果您在表达式中创建临时变量,它将持续到该完整表达式的末尾。因此,可以将临时参数作为函数参数(按值或引用)除非该函数存储对该参数的引用,并且稍后会尝试使用该引用。这就是您的第一个循环所做的 - match 包含对已失效临时文件的引用。
  • 感谢@MikeSeymour,您的评论澄清了这个问题。因此,这里的重点是未分配的构造函数是一个临时的,“持续到完整表达式的末尾”。真的很难找到这些信息。
猜你喜欢
  • 2015-12-11
  • 1970-01-01
  • 2014-12-18
  • 1970-01-01
  • 2016-06-12
  • 2013-03-05
  • 1970-01-01
  • 2014-02-01
  • 2013-06-25
相关资源
最近更新 更多