在std :: for_each中使用std :: get<>()

时间:2013-06-20 08:28:09

标签: c++ visual-studio-2012 c++11

我有一个正在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<>是否可以在上面使用,或者为什么不使用。

2 个答案:

答案 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))