C++ std::绑定可变模板成员函数和通用引用

C++ std::绑定可变模板成员函数和通用引用,c++,c++11,templates,bind,variadic-templates,C++,C++11,Templates,Bind,Variadic Templates,在这里,我有一小段代码,它可以编译并工作得很好 (至少使用我的GCC 7.3.0和Ubuntu 18.04): 即使缺少引用,它也可以编译。 谁能解释一下这里到底发生了什么? 我也做了一些搜索,发现了这个问题: 但是我不完全理解答案。如果显式地将模板参数指定为int,那么func\u to\u bind的参数类型将变成int&,即右值引用类型。请注意,存储的参数通过以下方式作为lvalues传递给可调用对象: 否则,普通存储参数arg将作为左值参数传递给可调用对象: 无法将左值绑定到右值ref

在这里,我有一小段代码,它可以编译并工作得很好 (至少使用我的GCC 7.3.0和Ubuntu 18.04):

即使缺少引用,它也可以编译。 谁能解释一下这里到底发生了什么? 我也做了一些搜索,发现了这个问题:


但是我不完全理解答案。

如果显式地将模板参数指定为
int
,那么
func\u to\u bind
的参数类型将变成
int&
,即右值引用类型。请注意,存储的参数通过以下方式作为lvalues传递给可调用对象:

否则,普通存储参数arg将作为左值参数传递给可调用对象:

无法将左值绑定到右值referece参数,然后调用失败


如果将模板参数显式指定为
int&
,则
func\u to\u bind
的参数类型变为
int&
,即左值引用类型;左值可以绑定到左值引用,然后它就可以正常工作了


如果您将
func\u的参数类型更改为\u bind
ARGS&
,它将始终是一个左值引用,出于上述相同的原因,它将正常工作。

FWIW您不需要使用
std::bind
。lambda通常使代码更易于编写,并允许您避免指定模板参数,因为它可以为您使用重载解析和模板参数推断
func_obj
可以重写为
func_obj=[this](auto&&..args){return func_to_bind(42,args…)}所有都很好,但我所能使用的是C++ 11,它没有用于lambda的通用参数。
#include <functional>
#include <string>
#include <iostream>

void func(int a, const std::string& b, const std::string& c)
{
  std::cout << a << b << c << std::endl;
}

class Test
{
public:
  template <typename ... ARGS>
  bool func_to_bind(ARGS&& ... args) const {
    func(args...);
    return true;
  }

  template <typename ... ARGS>
  void binding_func(ARGS&& ... args) const 
  {
    auto func_obj = std::bind(&Test::func_to_bind<int&, ARGS&...>, this, 42, args...);
    func_obj();
  }
};


int main()
{
  Test obj;
  obj.binding_func(std::string("one"), std::string("two"));
}
std::bind(&Test::func_to_bind<int&, ARGS&...>, this, 42, args...);
std::bind(&Test::func_to_bind<int, ARGS&...>, this, 42, args...);
bool func_to_bind(ARGS& ... args) const