关于带有可变参数模板的std :: ref()和std :: bind()有点朦胧

Cur*_*ous 9 c++ templates variadic-templates c++11 c++14

我已经阅读了很多关于可变参数模板和std :: bind的帖子,但我想我仍然不理解它们如何协同工作.我认为我的概念在使用可变参数模板时会有点模糊,std :: bind用于什么以及它们如何结合在一起.

在下面的代码中,我的lambda使用点运算符和TestClass类型的对象,但即使我传入std :: ref类型的对象,它们仍然可以工作.这到底是怎么回事?隐式转换是如何发生的?

#include <iostream>
using std::cout;
using std::endl;
#include <functional>
#include <utility>
using std::forward;

class TestClass {
public:
    TestClass(const TestClass& other) {
        this->integer = other.integer;
        cout << "Copy constructed" << endl;
    }
    TestClass() : integer(0) {
        cout << "Default constructed" << endl;
    }
    TestClass(TestClass&& other) {
        cout << "Move constructed" << endl;
        this->integer = other.integer;
    }

    int integer;
};

template <typename FunctionType, typename ...Args>
void my_function(FunctionType function, Args&&... args) {
    cout << "in function" << endl;
    auto bound_function = std::bind(function, args...);
    bound_function();
}

int main() {

    auto my_lambda = [](const auto& one, const auto& two) {
        cout << one.integer << two.integer << endl;
    };

    TestClass test1;
    TestClass test2;
    my_function(my_lambda, std::ref(test1), std::ref(test2));

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

更具体地讲,我通过与两个的reference_wrapper的两个实例TestClass对象test1test2,但是当我将它们传递到拉姆达的.运营商工作的神奇.我希望您使用::get()reference_wrapper中的函数来实现此功能,但对.integer数据成员的调用有效.

Ant*_*vin 5

参考展开由以下结果执行std::bind():

如果参数是类型std::reference_wrapper<T>(例如,std::refstd::cref在初始调用中使用bind),则T&存储在bound参数中的引用将传递给invocable对象.

相应的标准可以在N4140草案[func.bind.bind]/10中找到.

  • @Curious:值得一提的是你应该分别研究bind和variadic模板.它们没有任何异常的交互,在有或没有可变参数的情况下绑定行为完全相同,并且可变参数在有或没有绑定的情况下完全相同.因此,单独研究它们并不是头脑过载. (2认同)