我可能会遗漏一些明显的东西 - 为什么我不能以这种方式使用std :: get?
#include <map>
#include <iterator>
#include <set>
#include <algorithm>
#include <utility>
int main() {
std::map<int, double> some_map;
std::set<int> set_of_ints;
std::transform(
some_map.begin(),
some_map.end(),
std::inserter( set_of_ints, set_of_ints.begin() ),
std::get<0> );
return 0;
}
我试过的编译器是VS2010以及Ideone.com用于C ++ 14的一些编辑器(一些最近的GCC?)。这是后者的输出:
prog.cpp: In function 'int main()':
prog.cpp:17:28: error: no matching function for call to 'transform(std::map<int, double>::iterator, std::map<int, double>::iterator, std::insert_iterator<std::set<int> >, <unresolved overloaded function type>)'
std::get<0, int, double> );
^
prog.cpp:17:28: note: candidates are:
In file included from /usr/include/c++/4.9/algorithm:62:0,
from prog.cpp:5:
/usr/include/c++/4.9/bits/stl_algo.h:4152:5: note: template<class _IIter, class _OIter, class _UnaryOperation> _OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation)
transform(_InputIterator __first, _InputIterator __last,
^
/usr/include/c++/4.9/bits/stl_algo.h:4152:5: note: template argument deduction/substitution failed:
prog.cpp:17:28: note: couldn't deduce template parameter '_UnaryOperation'
std::get<0, int, double> );
^
In file included from /usr/include/c++/4.9/algorithm:62:0,
from prog.cpp:5:
/usr/include/c++/4.9/bits/stl_algo.h:4189:5: note: template<class _IIter1, class _IIter2, class _OIter, class _BinaryOperation> _OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation)
transform(_InputIterator1 __first1, _InputIterator1 __last1,
^
/usr/include/c++/4.9/bits/stl_algo.h:4189:5: note: template argument deduction/substitution failed:
prog.cpp:17:28: note: candidate expects 5 arguments, 4 provided
std::get<0, int, double> );
答案 0 :(得分:2)
编译器无法决定使用以下两个重载中的哪一个。
int std::get<0, int, double>(const std::tuple<int, double>&)
int std::get<0, int, double>(const std::pair<int, double>&)
我没有看到任何方法让编译器选择其中一个。
您可能必须使用lambda或定义T1 pair_first<T1, T2>(const std::pair<T1, T2>&)
函数,然后再传递pair_first
。
答案 1 :(得分:2)
将std::get<0>
替换为以下其中一项:
[]( std:: pair<const int, double> &x){return std:: get<0>(x);}
// or
[]( decltype( *some_map.begin() ) &x){return std:: get<0>(x);}
// or
[]( decltype(some_map)::value_type &x){return std:: get<0>(x);}
// or cast to a function pointer
(const int & (*)(std::pair<const int,double> &)) std::get<0,const int,double>
在clang 3.5.0上测试过。这会强制它std::get
使用pair
,而不是tuple
。
另外,也许你应该在每个人面前const
,如下:
[]( const std:: pair<const int, double> &x){return std:: get<0>(x);}
// or
[]( const decltype( *some_map.begin() ) &x){return std:: get<0>(x);}
// or
[]( const decltype(some_map)::value_type &x){return std:: get<0>(x);}
(实际上,我认为中间的decltype( *some_map.begin() )
会自动为我们做正确的约束。)
强制转换功能指针有点尴尬,必须让所有类型完全正确。
最后,受@ chris的启发,这是一个C ++ 14解决方案(如果你想将其复制并粘贴到其他代码中,还有一些完美的转发):
[](auto&& x){return std:: get<0>(std::forward<decltype(x)>(x));}