Perfect Forwarding Variadic Template for a standard theme

I am trying to create a std :: thread form that places a wrapper around code that is executed in a thread. Unfortunately, I cannot get it to compile due to my poor understanding of rvalues ​​and the type template FunctionI'm trying to pass. Here is my code:

#include <vector>
#include <thread>
#include <utility>

void Simple2(int a, int b) {}

template <typename Function, typename... Args>
void Wrapper(Function&& f, Args&&... a) {
  f(std::forward<Args>(a)...);
}

class Pool {
 public:
  template <typename Function, typename... Args>
  void Binder(Function&& f, Args&&... a) {
    std::thread t(Wrapper<Function, Args...>,
                  std::forward<Function>(f), std::forward<Args>(a)...);
  }
};

int main() {
  Wrapper(Simple2, 3, 4);       // Works

  Pool pool;
  pool.Binder(Simple2, 3, 4);   // Doesn't compile
}

The Clang3.0 output, which seems important here:

/usr/include/c++/4.6/functional:1286:9: error: non-const lvalue reference to type 'void (int, int)' cannot bind to a value of unrelated type 'void (*)(int, int)'

and

note: in instantiation of function template specialization 'std::thread::thread<void (void (&)(int, int), int &&, int &&), void (&)(int, int), int, int>' requested here

I think that he alludes to the discrepancy between Wrapper<Function, Args...>and rvalues f, a..., passed std :: thread.

Curiously, this compiles in GCC4.9 and a newer Clang if I change std::forward<Function>(f)to std::ref(f).

+4
source share
1

, . :

pool.Binder(&Simple2, 3, 4);  

. , , Binder :

class Pool {
 public:
  template <typename Function, typename... Args>
  void Binder(Function&& f, Args&&... a) {
    std::thread t(Wrapper<typename std::decay<Function>::type, Args...>,
                  std::forward<Function>(f), std::forward<Args>(a)...);
  }
};

++ 14 :

class Pool {
 public:
  template <typename Function, typename... Args>
  void Binder(Function&& f, Args&&... a) {
    std::thread t(Wrapper<std::decay_t<Function>, Args...>,
                  std::forward<Function>(f), std::forward<Args>(a)...);
  }
};
+5

All Articles