我有一个正在std::for_each
循环中迭代的地图。我使用嵌套绑定和简单的帮助函数来获取我需要的对的元素。这必须可以从pre c ++ 11代码中使用。
typedef std::map<int, Foo> MapType;
std::for_each(
testMap.begin() ,
testMap.end() ,
std::bind(
&Foo::myIncredibleFunction ,
std::bind(
&ValueExtractor< MapType::key_type , MapType::mapped_type >::getValue,
std::placeholders::_1 )));
这很好(虽然我确信可以改进)
我也将把当前代码库从当前级别迁移到C ++ 11 ,所以我正在研究是否可以使用改进代码的语言(可读性,效率)。例如,我尝试了以下(不成功 - 请参阅下面的模板错误)
std::for_each(
testMap.begin() ,
testMap.end() ,
std::bind(
&Foo::myIncredibleFunction ,
std::get<1>( std::placeholders::_1 )));
错误
1>d:\projects\test_bind\test_bind\test_bind.cpp(48): error C2780:
std::bind ...<Snip>...
: expects 6 arguments - 2 provided
intellisense还有以下内容:
IntelliSense: no instance of overloaded function "std::get" matches the argument list
argument types are: (std::_Ph<1>)
我尝试了std:get<1>()
的各种用法组合,试图取代我的内部绑定但没有成功。我怀疑我没有理解这一点,但感觉我应该能够做我想做的事情。有没有办法使用std::get
调用并且没有辅助函数/函数来执行此操作?
编辑:我认为KennyTM提出了我在代码中实际做的答案,它比我的方法好得多。我仍然感兴趣的是std::get<>
是否可以在上面使用,或者为什么不使用。
答案 0 :(得分:3)
由于您已经在使用C ++ 11,为什么不使用基于范围的for循环(VS 2012支持)?
for (auto&& item : testMap) {
item.second.myIncredibleFunction();
}
答案 1 :(得分:2)
你的问题是std::get<1>(_1)
本身就是一个非常好的函数调用。
您要在此处执行的操作称为函数组合,可以使用嵌套绑定调用来完成此操作,例如std::bind(foo, std::bind(bar, _1))
。这里的问题是第二部分,其中bar = std::get<1>
- std::bind(&std::get<1>, _1)
将是明显的第一次尝试,但这不起作用,因为std::get
需要更多的模板参数。
一个解决方案是自定义函数对象:
#include <utility>
template<unsigned I>
struct get{
template<class T>
auto operator()(T&& v) -> decltype(std::get<I>(std::forward<T>(v)))
{ return std::get<I>(std::forward<T>(v)); }
};
然后:std::bind(&Foo::myIncredibleFunction, std::bind(get<1>(), _1))
。