使用 for_each 提升 sub_range;为啥我得到一个常量引用?
Posted
技术标签:
【中文标题】使用 for_each 提升 sub_range;为啥我得到一个常量引用?【英文标题】:Boost sub_range with for_each; why am I getting a const-reference?使用 for_each 提升 sub_range;为什么我得到一个常量引用? 【发布时间】:2014-02-09 08:37:26 【问题描述】:在 OS X Mavericks 上,使用 boost 1.55.0 和 clang-500.2.79(基于 LLVM 3.3svn),我正在尝试使用 boost::for_each
和 @987654323 迭代 std::map
中的子范围@。在我的函数对象中,我希望收到一个 std::pair &。相反,我似乎收到了一个 const std::pair &。为什么?
#include <map>
#include <boost/range/algorithm.hpp>
#include <boost/range/sub_range.hpp>
using std::map;
using std::begin;
using std::end;
using std::pair;
using boost::for_each;
using boost::sub_range;
int main()
map<int, int> myMap;
sub_range<decltype(myMap)> s
begin(myMap),
end(myMap)
;
auto f1 = [&](const pair<int, int> &)
;
for_each(s, f1); // Compiles fine
auto f2 = [&](pair<int, int> &)
;
for_each(s, f2); // Fails to compile
/Users/ambarish> clang++ main.cxx
In file included from main.cxx:1:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:371:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:18:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/algorithm:793:9: error: no matching function for call to object of type '<lambda at main.cxx:24:15>'
__f(*__first);
^~~
/usr/local/include/boost/range/algorithm/for_each.hpp:80:12: note: in instantiation of function template specialization
'std::__1::for_each<std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int, int>, std::__1::__tree_node<std::__1::pair<int, int>, void *> *, long> >, <lambda at main.cxx:24:15> >'
requested here
return std::for_each<
^
main.cxx:26:5: note: (skipping 1 context in backtrace; use -ftemplate-backtrace-limit=0 to see all)
for_each(s, f2);
^
main.cxx:24:15: note: candidate function not viable: no known conversion from 'value_type' (aka 'pair<__key_type, __mapped_type>') to 'pair<int, int> &' for 1st argument
auto f2 = [&](pair<int, int> &)
^
1 error generated.
【问题讨论】:
【参考方案1】:因为std::map<int, int>
的值类型不是std::pair<int,int>
而是std::pair<const int, int>
,所以无法编译。
第一个 (f1
) 编译的原因是因为std::pair
有这个构造函数:
template< class U1, class U2 >
pair( pair<U1, U2>&& p );
因为f1
通过 const 引用获取参数。现在有一个合适的转换可以生成一个可以轻松绑定到 const 引用的临时对象。
修复:
auto f2 = [&](pair<const int, int> &) ;
// or
auto f2 = [&](pair<int, int>) ;
【讨论】:
【参考方案2】:代码似乎在 boost 库实现中使用 std::for_each,并且 C++11 风格的标准 lambdas 无论如何都被传递给 for_each 函数。这实际上取决于库如何将容器的迭代器传递给 std::for_each
【讨论】:
以上是关于使用 for_each 提升 sub_range;为啥我得到一个常量引用?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C++ 中使用 for_each 累积结果? [复制]