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

using std::get<>() in std::for_each

本文关键字:std lt get gt for each      更新时间:2023-10-16

我有一个在std::for_each循环中迭代的映射。我使用嵌套绑定和简单的辅助函数来获取所需的对中的元素。

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:projectstest_bindtest_bindtest_bind.cpp(48): error C2780:
    std::bind ...<Snip>...
    : expects 6 arguments - 2 provided

也有以下智能感知:

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<>是否可以使用或为什么不使用感兴趣。

既然你已经在使用c++ 11了,为什么不使用一个基于范围的for循环(这在VS 2012中是支持的)?

for (auto&& item : testMap) {
    item.second.myIncredibleFunction();
}

您的问题是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)) .