为什么这样使用 find_if 会失败?
Why using find_if like this fail?
我想从地图中找到第一个非零元素,因此我做了以下代码:
#include <map>
#include <iostream>
#include <algorithm>
bool nonzero(std::map<char,int>::const_iterator& it);
int main() {
std::map<char, int> m;
m['a'] = 0;
m['b'] = 1;
std::map<char,int>::iterator it = std::find_if(m.begin(), m.end(), nonzero);
std::cout << it->first << '\t' << it->second << std::endl;
return 0;
}
bool nonzero(std::map<char,int>::const_iterator& it) {
return it->second;
}
g++给出的错误很复杂,说的是:
/usr/include/c++/5/bits/predefined_ops.h:234:30: error: invalid initialization of reference of type ‘std::_Rb_tree_const_iterator<std::pair<const char, int> >&’ from expression of type ‘std::pair<const char, int>’
{ return bool(_M_pred(*__it)); }
我不明白它在说什么以及为什么我的程序会失败。
find_if
将value_type
(实际上是iterator.operator*()
)传递给传递给它的function/function对象。您的 nonzero
应该接受 std::map<char,int>::value_type const&
作为参数,或者更简洁地说:std::pair<const char, int> const&
bool nonzero(std::pair<const char, int> const& element) {
return it.second;
}
请注意,该对的密钥是 const
。如果您省略它,您将复制您检查的每个地图元素。
如果您可以使用 C++14 或更新版本,您还可以使用 auto
和通用 lambda 使其更短:
auto it = std::find_if(m.begin(), m.end(), [](auto const& pair){ return p.second; });
和C++11版本:
auto it = std::find_if(m.begin(), m.end(), [](std::pair<const char, int> const& pair){ return p.second; })
函数接受:
bool nonzero(const std::map<char,int>::value_type& value);
这是std::pair<const char,int>
,不是迭代器
在使用该迭代器之前,您应该通过与 std::map::end()
进行比较来检查 find_if
的结果。
find_if
调用的 nonzero
函数的预期类型是 而不是 std::map<char,int>::const_iterator&
,而是 const std::pair<const char, int> &
。
事实上,如果您检查一些 online documentation for find_if
,您会看到一元谓词具有以下形式:
bool UnaryPredicate(const Type&)
其中 Type
在您的案例中是 std::pair<const char, int>
(对于一般 std::map<Key, Value>
,类型是 std::pair<const Key, Value>
)。
所以你可以调整你的函数传递一个 const&
到那个 std::pair
:
bool nonzero(const std::pair<const char, int> & p)
{
return (p.second != 0);
}
请注意,将 C++14 auto
与 lambda 一起使用会简化您的代码,例如:
auto it = std::find_if(m.begin(), m.end(), [](const auto& p){
return (p.second != 0);
});
另请注意,该对的一般形式为 std::pair<const Key, Value>
(不仅仅是带有非常量键的 pair<Key, Value>
)。
我想从地图中找到第一个非零元素,因此我做了以下代码:
#include <map>
#include <iostream>
#include <algorithm>
bool nonzero(std::map<char,int>::const_iterator& it);
int main() {
std::map<char, int> m;
m['a'] = 0;
m['b'] = 1;
std::map<char,int>::iterator it = std::find_if(m.begin(), m.end(), nonzero);
std::cout << it->first << '\t' << it->second << std::endl;
return 0;
}
bool nonzero(std::map<char,int>::const_iterator& it) {
return it->second;
}
g++给出的错误很复杂,说的是:
/usr/include/c++/5/bits/predefined_ops.h:234:30: error: invalid initialization of reference of type ‘std::_Rb_tree_const_iterator<std::pair<const char, int> >&’ from expression of type ‘std::pair<const char, int>’
{ return bool(_M_pred(*__it)); }
我不明白它在说什么以及为什么我的程序会失败。
find_if
将value_type
(实际上是iterator.operator*()
)传递给传递给它的function/function对象。您的 nonzero
应该接受 std::map<char,int>::value_type const&
作为参数,或者更简洁地说:std::pair<const char, int> const&
bool nonzero(std::pair<const char, int> const& element) {
return it.second;
}
请注意,该对的密钥是 const
。如果您省略它,您将复制您检查的每个地图元素。
如果您可以使用 C++14 或更新版本,您还可以使用 auto
和通用 lambda 使其更短:
auto it = std::find_if(m.begin(), m.end(), [](auto const& pair){ return p.second; });
和C++11版本:
auto it = std::find_if(m.begin(), m.end(), [](std::pair<const char, int> const& pair){ return p.second; })
函数接受:
bool nonzero(const std::map<char,int>::value_type& value);
这是std::pair<const char,int>
,不是迭代器
在使用该迭代器之前,您应该通过与 std::map::end()
进行比较来检查 find_if
的结果。
find_if
调用的 nonzero
函数的预期类型是 而不是 std::map<char,int>::const_iterator&
,而是 const std::pair<const char, int> &
。
事实上,如果您检查一些 online documentation for find_if
,您会看到一元谓词具有以下形式:
bool UnaryPredicate(const Type&)
其中 Type
在您的案例中是 std::pair<const char, int>
(对于一般 std::map<Key, Value>
,类型是 std::pair<const Key, Value>
)。
所以你可以调整你的函数传递一个 const&
到那个 std::pair
:
bool nonzero(const std::pair<const char, int> & p)
{
return (p.second != 0);
}
请注意,将 C++14 auto
与 lambda 一起使用会简化您的代码,例如:
auto it = std::find_if(m.begin(), m.end(), [](const auto& p){
return (p.second != 0);
});
另请注意,该对的一般形式为 std::pair<const Key, Value>
(不仅仅是带有非常量键的 pair<Key, Value>
)。