如何使用 MSVC2015 将带有局部变量的一些参数的函数包装器放置到容器中?

How to emplace a function wrapper with some arguments from local variables into container with MSVC2015?

我在看 。但是我无法弄清楚,基于那个例子,为什么我不能用 MSVC 2015 编译器绑定某个局部变量的值?它只是抛出一个错误,而 gcc 5.3 在 msys2/mingw64 上编译它很好。我的意思是像

#include <iostream>
#include <functional>
#include <vector>

int add(int a, int b) { return a + b; }

using bound_add_t = decltype(std::bind(add, std::placeholders::_1, int()));

int main() {
  std::vector<bound_add_t> vec;
  int y = 2;
  vec.emplace_back(add,std::placeholders::_1, y); // <- this causes the problem
  vec.emplace_back(add,std::placeholders::_1, 2);
  vec.emplace_back(add,std::placeholders::_1, 3);

  for (auto &b : vec)
    std::cout << b(5) << std::endl;

  return 0;   
}

严重性代码说明项目文件行抑制状态 错误 C2664 'std::_Binder &,int>::_Binder(std::_Binder &,int> &&)':无法将参数 3 从 'int' 转换为 'int &&' C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0 655

这是在某处追踪到的已知问题吗?我什至不确定这里的根本问题是什么。有解决方法吗?

在我的用例中,我遗漏了一个稍后可用的参数,所以我想准备一个带有包装函数的向量,就像在那个例子中一样。

更新

它是 C++14 的东西吗?我在 http://ideone.com/Zi1Yht 上闲逛。虽然没有 MSVC,但只有标记为 C++14 的编译器才能编译它。

更新 2

我试过了

std::vector<std::function<int(int)> > vec;
vec.emplace_back(add, std::placeholders::_1, y);

如果这是暗示,我得到

严重性代码说明项目文件行抑制状态 错误 C2664 'std::function::function(std::function &&)':无法将参数 1 从 'int (__cdecl &)(int,int)' 转换为 'std::allocator_arg_t' C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0 655

std::bind 的 return 类型 未指定

所需的构造函数是复制构造函数或移动构造函数。

根据您提供的参数(函数、占位符...)构建它是未指定的,可能适用于特定的实现,但不可移植。

作为解决方法,您可以这样做

std::vector<std::function<int(int)> > vec;
int y = 2;

vec.push_back(std::bind(add, std::placeholders::_1, y));
vec.push_back(std::bind(add, std::placeholders::_1, 2));
vec.push_back(std::bind(add, std::placeholders::_1, 3));

MSVC 有权拒绝此代码。 int() 是一个临时参数,因此相应的 Args&&... 参数推导为 int&&。所以bind结果类型的构造函数可以把int&&作为最后一个参数,而y不是右值所以编译失败。

这不是其他编译器中的错误,因为 bind 的结果未指定。

如果您不想回退到 std::function,您可以将最后一个参数的类型强制为 const int&:

using bound_add_t = decltype(std::bind(add, std::placeholders::_1, std::declval<const int&>()));