如何从 lambda 函数返回 nullptr?

问题描述 投票:0回答:3

我有一个小的 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:“nullptr”:lambda 中的所有返回表达式必须具有相同的类型:以前是“QTreeWidgetItem *”cpp 251

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

return (QTreeWidgetItem*)( nullptr );

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

我用

Visual Studio 2012

c++ lambda
3个回答
16
投票

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

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

这样

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


作为旁注,请考虑使用

(std::)optional
代替。指针的可为空性可以用来表示缺少返回,但这并不意味着它一定应该如此。


4
投票

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

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;
}

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;
};
© www.soinside.com 2019 - 2024. All rights reserved.