如何从lambda函数返回nullptr?

时间:2015-06-11 14:00:52

标签: c++11 lambda

我有一个小的lambda函数,它将找到并返回QTreeWidgetItem。但是如果找不到给定的项目,那么它将返回nullptr。但是,如果我尝试编译它,那么它会给我一个错误。

功能:

auto takeTopLevelItem = []( QTreeWidget* aTreeWidget, const QString& aText )
{
    const int count = aTreeWidget->topLevelItemCount();
    for ( int index = 0; index < count; ++index )
    {
        auto item = aTreeWidget->topLevelItem( index );
        if ( item->text( 0 ) == aText )
        {
            return aTreeWidget->takeTopLevelItem( index );
        }
    }
    return nullptr; // This causes a compilation error.
};

错误:

  

错误1错误C3487:&#39; nullptr&#39;:lambda中的所有返回表达式必须具有相同的类型:以前它是&#39; QTreeWidgetItem *&#39; cpp 251

我用这个改变了提到的行,现在它编译:

return (QTreeWidgetItem*)( nullptr );

但我想避免这种语法。我该如何解决这个问题?

我使用Visual Studio 2012

3 个答案:

答案 0 :(得分:13)

您可以添加显式返回类型注释:

auto takeTopLevelItem = []( ... ) -> QTreeWidgetItem*
{
    // ...
}

这样nullptr将正确转换为您的指针类型。您收到该错误是因为lambda假定不应进行任何转换,并将nullptr_t视为合法的替代返回类型。

作为旁注,请考虑使用(std::)optional。指针的可空性可用于表示缺失的回报,但它并不意味着它必然应该是。

答案 1 :(得分:2)

如果你只是想避免语法,而不是强制转换,你可以这样:

static_cast<QTreeWidgetItem*>(nullptr);

我做了一个小例子,关于Bartek和我的回答是如何运作的:

#include <iostream>

class A {
  int a;
};

auto bla = [] (A* obj, bool flag) -> A* {
  if(flag)
    return obj;
  return nullptr;
//  return static_cast<A*>(nullptr);
};

int main() {
  A obj;
  A* ptr = &obj;
  bool flag = false;
  if( bla(ptr, flag) == nullptr)
    std::cout << "ok\n";
  return 0;
}

答案 2 :(得分:0)

我在使用一些智能指针时遇到了同样的问题,所以我发现我可以这样做来避免这个问题:

auto myFunc= [](MyClass* class)
{
    MyPointer* pointer = nullptr;
    
    if( class && class->isValid() )
    {
       pointer = class->getPointerInstance()
    }
    
    return pointer;
}

同样,对于共享指针,只需将 MyPointer* 替换为 std::shared_ptr<MyPointer>

所以你的代码看起来像:

auto takeTopLevelItem = []( QTreeWidget* aTreeWidget, const QString& aText )
{
  QTreeWidgetItem* item = nullptr;
  const int count = aTreeWidget->topLevelItemCount();
  for ( int index = 0; index < count; ++index )
  {
      auto item = aTreeWidget->topLevelItem( index );
      if ( item->text( 0 ) == aText )
      {
          item = aTreeWidget->takeTopLevelItem( index );
          break;
      }
  }
  return item;
};