Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++14 lambda with init capture does not generate valid code #258

Closed
sweenish opened this issue Oct 18, 2019 · 1 comment
Closed

C++14 lambda with init capture does not generate valid code #258

sweenish opened this issue Oct 18, 2019 · 1 comment
Labels
bug Something isn't working

Comments

@sweenish
Copy link

This is the code I wanted to see expanded; it is valid C++ and compiles fine on my Catalina MBP.

#include <iostream>
#include <memory>

int main()
{
    auto x = std::make_unique<int>(42);
    auto lambda = [x = std::move(x)]() { std::cout << *x << '\n'; };
}

Here is the generated code:

#include <iostream>
#include <memory>

int main()
{
  std::unique_ptr<int, std::default_delete<int> > x = std::unique_ptr<int, std::default_delete<int> >(std::make_unique<int>(42));
    
  class __lambda_7_19
  {
    public: 
    inline void operator()() const
    {
      std::operator<<(std::cout.operator<<(x.operator*()), '\n');
    }
    
    private: 
    std::unique_ptr<int, std::default_delete<int> > x;
    public: 
    // inline __lambda_7_19(const __lambda_7_19 &) = delete;
    // inline __lambda_7_19(__lambda_7_19 &&) noexcept = default;
    public: __lambda_7_19(std::unique_ptr<int, std::default_delete<int> > _x)
    : x{_x}  // *** ERROR HERE ON _x ***
    {}
    
  };
  
  __lambda_7_19 lambda = __lambda_7_19(__lambda_7_19{std::unique_ptr<int, std::default_delete<int> >(std::move(x))});
}

And this is the error message I get from the generated code:

std::__1::unique_ptr<int, std::__1::default_delete<int>> _x
function "std::__1::unique_ptr<_Tp, _Dp>::unique_ptr(const std::__1::unique_ptr<int, std::__1::default_delete<int>> &) throw() [with _Tp=int, _Dp=std::__1::default_delete<int>]" (declared implicitly) cannot be referenced -- it is a deleted function

The generated constructor attempts to make a copy of a type I am attempting to init capture in my lambda. This type also happens to be non-copyable. For reference, if it was a vector instead of unique_ptr, the generated code works because it can be [and is] copied.

I am experiencing this error using the website cppinsights.io, and using C++14 with the option "show all implicit casts" checked.

@andreasfertig andreasfertig added the bug Something isn't working label Oct 18, 2019
@andreasfertig
Copy link
Owner

Hello @sweenish,

thank you for reporting this. At this point there is some lifting involved to generate the code of the lambda. I check whether it is possible to handle this case correctly.

Andreas

andreasfertig added a commit that referenced this issue Oct 27, 2019
Fixed #258: Apply `std::move` to init-captures in lambdas.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants