Naios / function2

Improved and configurable drop-in replacement to std::function that supports move only types, multiple overloads and more
http://naios.github.io/function2
Boost Software License 1.0
539 stars 47 forks source link

Compilation error of fu2::unique_function having a capture [ std::vector< std::vector < std::unique_ptr<int> > > ] #14

Closed scherno2000 closed 6 years ago

scherno2000 commented 6 years ago

@Naios

The code attached does not compile. This is probably because of the two dimensional vector of uncopyable objects (unique_ptrs)

By uncommenting the dummy variable at the line 31 in the capture the code compiles and runs as expected


Commit Hash

Latest commit e30dbbe on 13 Apr

Expected Behavior

To be compilable, and functioning

Actual Behavior

It doesn't compile, error message:

D:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev0\mingw64\lib\gcc\x86_64-w64-mingw32\7.2.0\include\c++\bits\stl_construct.h|75|error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete]'|

Steps to Reproduce

Please use the example code given in the attachment

main.zip

Your Environment

Naios commented 6 years ago

Thanks for reporting this issue.

I could narrow the test case down to:

static fu2::unique_function<void()> issue_14_create() {
  // remove the commented dummy capture to be compilable
  fu2::unique_function<void()> func =
      [
        i = std::vector<std::vector<std::unique_ptr<int>>>{}
        // ,dummy = std::unique_ptr<int>()
      ]() {
        // ...
      };

  return std::move(func);
}

// https://github.com/Naios/function2/issues/14
TEST(regression_tests, issue_14) {
  issue_14_create()();
}

I'll investigate into this.

scherno2000 commented 6 years ago

1) I discovered that is not necessary a double dimension vector

static fu2::unique_function<void()> issue_14_create() {
  // remove the commented dummy capture to be compilable
  fu2::unique_function<void()> func =
      [
        i = std::vector<std::unique_ptr<int>>{}
        // ,dummy = std::unique_ptr<int>()
      ]() {
        // ...
      };

  return std::move(func);
}

2) I found a workaround by encapsulating the vector inside a struct

struct vector_wrapper
{
    std::vector<std::unique_ptr<int>> vec;
    vector_wrapper() = default;
    vector_wrapper(vector_wrapper&& v):
        vec(std::move(v.vec))
        {}
};

static fu2::unique_function<void()> issue_14_create() {
  // remove the commented dummy capture to be compilable
  fu2::unique_function<void()> func =
      [
        i = vector_wrapper{}
      ]() {
        // ...
      };

  return std::move(func);
}
Naios commented 6 years ago

Thanks for your bug report. It was fixed due to version v3.1.0.