如何将可变参数模板参数绑定到函数

时间:2014-01-25 10:26:49

标签: c++ c++11

我正在尝试模仿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线程,它们在构建后没有立即执行。

1 个答案:

答案 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_;
};

Also see this live example

如果您希望存储可变电池包,请参阅以下答案:How to store variadic template arguments?