如何将带有局部变量的一些参数的函数包装器放入具有MSVC2015的容器中

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

本文关键字:包装 MSVC2015 参数 局部变量 函数      更新时间:2023-10-16

我正在寻找另一个问题的答案。但是,根据该示例,我无法弄清楚为什么我不能将某些局部变量的值与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

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&>()));

未指定std::bind的返回类型。

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

从您给出的参数(函数、占位符等(构造它是未指定的,可能适用于特定实现,但不可移植。

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

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