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

问题描述 投票:0回答:1

这里我只有一小段代码,它可以编译并正常工作(至少在我的GCC 7.3.0和Ubuntu 18.04中):

#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...);

为什么编译器需要使用引用作为模板类型参数?如果我像这样从int删除引用:

std::bind(&Test::func_to_bind<int, ARGS&...>, this, 42, args...);

它不会编译。另外,如果我将func_to_bind签名更改为此:

bool func_to_bind(ARGS& ... args) const

即使缺少参考,它也可以正常编译。谁能解释这到底是怎么回事?我也做了一些搜索,发现了这个问题:How to combine std::bind(), variadic templates, and perfect forwarding?

但是我不完全理解答案。

c++ templates bind variadic-templates
1个回答
0
投票

如果您将模板参数明确指定为int,则func_to_bind的参数类型将变为int&&,即右值引用类型。注意,存储的参数作为左值参数由std::bind

传递给可调用对象。

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

左值不能绑定到右值参考参数,然后失败。

© www.soinside.com 2019 - 2024. All rights reserved.