如何使用 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&>()));
我在看
#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&>()));