我正在尝试模仿std :: thread构造函数:
template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
我尝试使用调试器来查看它是如何工作的,但我无法理解它。
如何像线程的构造函数一样创建和存储绑定类型?
这样的东西(语法可能不对):
class myClass{
private:
auto bindType;
public:
template< class Function, class... Args >
explicit myClass( Function&& f, Args&&... args ) : bindType(somehowBind(f, args) {}
void evaluate() {bindType();}
};
使用示例:
int test(int i) {return i;}
int main(){
myClass my(test, 5);
my.evaluate();
}
请注意,我不关心somehowBind
函数是否会忽略返回类型,即它的返回类型可能类似于std :: function。
我不想做的就是理解如何将class... Args
绑定到给定的函数f
,这样在调用somehowBind
之后它将像std :: bind一样。
为了澄清我的观点,你可以考虑我想要实现的目标如下:
thread t(test, 5); // unlike the usual std:::thread, this one is created in suspended mode therefore I need somehow to bind `f` with `5` and store it
t.start(); // now t is executed
它有点提醒C#和Java线程,它们在构建后没有立即执行。
答案 0 :(得分:4)
对于初学者来说,要使用std::bind
将一些参数绑定到一个函数,你可以这样做:
// Some function.
void printValues(int x, double y) {
std::cout << x << " " << y << std::endl;
}
auto func = std::bind(printValues, 5, 2.0); // Bind params and return functor.
func(); // Evaluate function call (returns void in this case).
接下来,要将一个仿函数及其参数存储在一个类中,并且在评估时不关心返回值,那么只需使用一个lambda表达式来包装std::bind
表达式(lambda用于删除返回值):
struct Foo {
template <typename Function, typename... Args>
Foo(Function&& func, Args&&... args) {
auto f = std::bind(std::forward<Function>(func), std::forward<Args>(args)...);
func_ = [f] { f(); };
// func_ = [f{std::move(f)}] { f(); }; // In C++14 you can move capture.
}
void evaluate() { func_(); }
std::function<void()> func_;
};
如果您希望存储可变电池包,请参阅以下答案:How to store variadic template arguments?