换行std::thread调用函数

Wrap std::thread call function

我想控制 threads,所以每个新发布的 thread 都会先通过我的代码。
这样,在下面的示例中,每个使用 runThread() 发出的新线程将首先调用下面的函数 runInnerThread()(我在其中进行某种初始化),然后调用所需的函数。

我试过这样写:

#include <iostream>
#include <thread>

template<typename _Callable, typename... _Args>
void runThreadInner(_Callable&& __f, _Args&&... __args) {
    // My initializations...
    __f(__args...);
    // My finishing...
};

template<typename _Callable, typename... _Args>
bool runThread(_Callable&& __f, _Args&&... __args) {
    std::thread t(std::bind(&runThreadInner,
                            std::forward<_Callable>(__f),
                            std::forward<_Args>(__args)...));
}

int main() {
    runThread([]() {
        std::cout << std::this_thread::get_id() << "Threading...\n";
    });
    return 0;
}

我从编译器那里得到一个错误,它抱怨推导 runThreadInner() 模板

main.cpp: In instantiation of ‘bool runThread(_Callable&&, _Args&& ...) [with _Callable = main()::__lambda0; _Args = {}]’:
main.cpp:43:3:   required from here
main.cpp:27:38: error: no matching function for call to ‘bind(<unresolved overloaded function type>, main()::__lambda0)’
        std::forward<_Args>(__args)...));
                                      ^
main.cpp:27:38: note: candidates are:
In file included from /usr/include/c++/4.8/memory:79:0,
                 from main.cpp:2:
/usr/include/c++/4.8/functional:1655:5: note: template<class _Func, class ... _BoundArgs> typename std::_Bind_helper<std::__or_<std::is_integral<typename std::decay<_Tp>::type>, std::is_enum<typename std::decay<_Tp>::type> >::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ...)
     bind(_Func&& __f, _BoundArgs&&... __args)
     ^
/usr/include/c++/4.8/functional:1655:5: note:   template argument deduction/substitution failed:
main.cpp:27:38: note:   couldn't deduce template parameter ‘_Func’
        std::forward<_Args>(__args)...));
                                      ^
In file included from /usr/include/c++/4.8/memory:79:0,
                 from main.cpp:2:
/usr/include/c++/4.8/functional:1682:5: note: template<class _Result, class _Func, class ... _BoundArgs> typename std::_Bindres_helper<_Result, _Func, _BoundArgs>::type std::bind(_Func&&, _BoundArgs&& ...)
     bind(_Func&& __f, _BoundArgs&&... __args)
     ^
/usr/include/c++/4.8/functional:1682:5: note:   template argument deduction/substitution failed:
main.cpp:27:38: note:   couldn't deduce template parameter ‘_Result’
        std::forward<_Args>(__args)...));

我尝试明确定义模板,但没有成功:

template<typename _Callable, typename... _Args>
bool runThread(_Callable&& __f, _Args&&... __args) {
    std::thread t(std::bind(&runThreadInner<_Callable, _Args>,
                            std::forward<_Callable>(__f),
                            std::forward<_Args>(__args)...));
}

可能吗? 谢谢。

简单易行。

#include <thread>
#include <iostream>

template<typename Callable, typename... Args>
void runThreadInner(Callable&& f, Args&&... args) {
    // My initializations...
    f(args...);
    // My finishing...
};

template<typename Callable, typename... Args>
std::thread runThread(Callable&& f, Args&&... args) {
    std::thread t(&runThreadInner<Callable, Args...>, 
         std::forward<Callable> (f), std::forward<Args>(args)...);
    return t;
}
int main() {
    auto t = runThread([]() {
        std::cout << "Threading..." << std::endl;
    });
    t.join();
    return 0;
}

您可能缺少 #include <functional>(其中定义了 std::bind)。

但是,您的情况并不需要 std::bind,因为您有 lambda,在很多方面都是 better

这是一个没有 std::bind 的工作示例:

#include <iostream>
#include <functional>
#include <thread>
#include <utility>

template <typename F>
struct MyTaskWrapper {
  F f;

  template <typename... T>
  void operator()(T&&... args) {
    std::cout << "Stuff before...\n";
    f(std::forward<T>(args)...);
    std::cout << "Stuff after...\n";
  }

};

template <typename F, typename... Args>
void runThread(F&& f, Args&&... args) {
  std::thread trd(MyTaskWrapper<F>{std::forward<F>(f)}, std::forward<Args>(args)...);
  trd.join();
}

int main() {
  runThread([] {
    std::cout << "Threading...\n";
  });
}

输出:

Stuff before...
Threading...
Stuff after...

Live demo

您的代码有问题。我会拒绝代码审查中的几乎每一行。

_Capital 不是合法的 C++。 __lower 也不是。停止复制 system 和 std headers 所做的事情,它们是允许的,但你不允许。他们这样做 正是因为你现在被允许 保证他们的代码不会与你做愚蠢的预处理器事情重叠(以任何合法的方式)。

template<typename Callable>
std::thread runThread(Callable&& f) {
  std::thread t([=]{
    // My initializations...
    f();
    // My finishing...
  });
  return t;
}

int main() {
  auto t = runThread([]() {
    std::cout << std::this_thread::get_id() << "Threading...\n";
  });
  t.join();
}

如果有人想绑定参数,让他们在自己调用 runThread 时进行绑定。