【问题标题】:Return pointer to local variable?? (warning C4172)返回指向局部变量的指针?? (警告 C4172)
【发布时间】:2013-04-17 13:33:42
【问题描述】:

好吧,视觉工作室给了我一个警告。我确实理解警告并且我知道这不是错误。但是我不明白为什么我会看到警告 - 更糟糕的是,我因此不明白如何预防/它可能带来哪些潜在问题。

代码如下所示,该函数应通过在容器中查找给定的“id”来返回对std::function<> (fun_type_cref) 的(常量)引用。
容器存储为[id, fun_type] 对。

Handler::fun_type_cref Handler::Overwrite() const
{
    auto i(container.find(OVERWRITE));
    if (i != container.end()) {
        return *i;
    } else {
        return nullptr;
    }
}

两个返回语句中出现的确切警告是

警告 C4172:返回局部变量或临时地址

是什么导致了这个错误?我只是返回对包含对象的引用,对吗? *i 不会创建对象的副本,对吧?我在任何地方都看不到自己在获取某物的地址?

我可以理解第二个,因为我返回了对本地创建的函数对象的引用,但是没有特定情况可以返回对编译时常量的引用或类似的东西吗?


编辑: 很好地解决了第一个问题,一个简单的类型不匹配,因为我忘了实际返回返回的迭代器的正确部分——应该是return i->second。奇怪的 Visual Studio 没有给我类型不匹配错误,编译器可以将 std::pair<std::string, std::function<...> > 转换为 std::function<...>

现在问题变成了关于第二个返回部分 - 我希望函数在“覆盖”ID 不在包含的函数表中时返回“默认值”(这将是一个 NO-OP)......如何定义这样的事情?因为我不想返回迭代器...

【问题讨论】:

  • 需要查看 fun_type_cref & container & nullptr 的声明。
  • @brianbeuning nullptr 是 C++11 标准功能。你想看它的什么声明?
  • 另外,fun_type_cref 只是对 std::function.. typedef std::function<...> fun_type 的引用; typedef const fun_type& fun_type_cref;
  • @paul23 那么容器呢?
  • @Loghorn typedef std::unordered_map fun_cont_type; - 现在使用“fun_type_id”作为 std::string...

标签: c++ scope return-by-reference


【解决方案1】:

尝试将 return i 替换为:

return (*i).second

【讨论】:

  • 啊,我真是太愚蠢了……奇怪的是,它并没有引发类型不匹配错误。 (为什么 std::pair 适合 std::function 类型)???现在问题变成了“如果找不到函数,我如何返回默认值”)。
  • @paul23:“奇怪的是它没有抛出”:std::function 有一个模板化的转换构造函数,所以任何类型都可以转换成它(尽管如果它不是可调用的,你应该得到错误类型)。在这里,它尝试从该对中创建一个临时函数对象并通过引用返回它。
  • "如果找不到函数,如何返回默认值"?您不能明智地这样做,因为您出于某种原因想要返回参考。为什么不按值返回?
  • @MikeSeymour 好吧,“现在”会起作用。然而,在未来,我将大量扩展这些“函数”,并且我可以预见相当多的函子具有需要在每次调用时记住/更新的内部状态。因此按值返回(并因此创建副本)可能会导致未来的问题。
  • @paul23:在这种情况下,我会考虑返回一个指针(如果未找到则返回 null),或者如果未找到则抛​​出异常。原则上,您可以定义一个静态的“默认”值并返回对其的引用,但请仔细考虑这是否真的是您想要的。
猜你喜欢
  • 1970-01-01
  • 2019-06-15
  • 2012-01-01
  • 2016-10-25
  • 1970-01-01
  • 2014-05-14
  • 2020-10-13
相关资源
最近更新 更多