换行std :: thread调用函数

时间:2018-01-15 17:56:12

标签: c++ multithreading c++11 stdthread

我想控制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)...));
}

有可能吗? 感谢。

3 个答案:

答案 0 :(得分:2)

您可能遗漏了seed-project(其中#include <functional>已定义)。

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

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

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";
  });
}

Live demo

答案 1 :(得分:1)

轻松自负。

#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;
}

答案 2 :(得分:0)

您的代码存在问题。我几乎拒绝了代码审查中的每一行。

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

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时这样做。