c++ - std::bind 可变参数模板成员函数和通用引用

标签 c++ c++11 templates bind variadic-templates

这里我有一小段代码,它编译并工作得很好 (至少对于我的 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?

但我并不完全理解答案。

最佳答案

如果你明确指定模板参数为int,那么func_to_bind的参数类型会变成int&&,即右值引用类型.请注意,存储的参数通过 std::bind 作为 lvalue 传递给可调用对象。 :

Otherwise, the ordinary stored argument arg is passed to the invokable object as lvalue argument:

左值不能绑定(bind)到右值引用参数,然后调用失败。

如果你显式指定模板参数为int&,那么func_to_bind的参数类型就变成了int&,即左值引用类型;左值可以绑定(bind)到左值引用然后它工作正常。

并且如果您将 func_to_bind 的参数类型更改为 ARGS&,它将始终是一个左值引用,出于与上述相同的原因,它可以正常工作。

关于c++ - std::bind 可变参数模板成员函数和通用引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58453009/

相关文章:

c++ - c++中非void return函数模板的显式方法

c++ - 单独对象的单一模板实例化

c++ - 在包含多个字符串的多个对象中查找子字符串

c++ - 无法解释的 malloc.c :2401: sysmalloc: Assertion Error

c++ - C++11 regex_search 和 ECMAScript 语法问题

c++ - tr1::function 可以吞下返回值吗?

c++ - 关于类模板成员的显式特化的困惑

c++ - 为什么用 std::string 和 std::string& 相似的函数初始化字符串?

c++ - 动态数组和求值之和的问题

c++ - "if"c++ 中的语句不从左到右计算条件