将lambda编译为Objective-C ++会导致块转换

时间:2019-12-11 19:46:21

标签: clang clang++ objective-c++

我有一个不可复制的C ++ lambda,它捕获了unique_ptr,在某些情况下,使用Apple Clang作为Objective-C ++进行编译时,会导致lambda转换为块指针,这时由于尝试复制而导致编译失败的lambda。一个简单的示例如下:

int main(int argc, const char * argv[])
{   
    std::unique_ptr<int> myHeapInt = std::make_unique<int>(4);
    int myStackInt = 0;

    auto myLambda = [&, myHeapInt = std::move(myHeapInt)]()
    {
        myStackInt = *myHeapInt;
    };

    if(bool(myLambda)) //Error ar this point
    {
        *myHeapInt = 5;
    }

    std::invoke(myLambda);

    return 0;
}

错误如下:

Call to implicitly-deleted copy constructor of 'const lambda...
Implicit capture of lambda object due to conversion to block pointer here

有没有办法解决这种转换?

3 个答案:

答案 0 :(得分:3)

bool(myLambda)是什么?我不知道。

使用lambda唯一可以做的就是调用它:myLambda()。您无法测试它是否存在。

答案 1 :(得分:0)

因此,我在这里没有完全看到Objective-C ++的相关性,因为此代码也不能编译为C ++:

objc++-noncopy-lambda.cpp:15:9: error: cannot convert '(lambda at objc++-noncopy-lambda.cpp:9:21)' to 'bool' without a conversion operator
    if (bool(myLambda))
        ^~~~~~~~~~~~~
1 error generated.

错误消息不同;我假设有人尝试在Objective-C ++中将lambda隐式转换为块,但我尝试避免这种奇怪的边缘情况,但是似乎在没有operator bool的情况下,它可能会尝试转换为首先是一个区块。

无论哪种方式,您尝试编写的代码都没有任何意义,并且编译器正确地拒绝了它。

我在评论中看到您实际上正在尝试做一些不同的事情。

也许您可以发布您实际上想编写的代码的简化版本,据称该版本编译为C ++,而不是Objective-C ++?

答案 2 :(得分:0)

我试图以Object-C ++的形式将std :: function(github.com/Naios/function2)的模板化头文件类替换为Object-C ++,该实现可实现vtable并对其进行优化(如果可调用实现了操作符bool()或可以转换为bool。

最后,我只是决定如果编译为Objective-C ++时禁用此优化,因为转换是根据Clang的设计来实现块-lambda互操作性(http://clang.llvm.org/docs/LanguageExtensions.html#interoperability-with-c-11-lambdas)的块指针。

相关问题