如何在find_if谓词中引用迭代器



我想确保一个字符串至少有一个字母。简单:

if ( find_if(field_name.begin(), field_name.end(), isalpha) == field_name.end() )

但我想使用locale.我知道我可以轻松地编写一个单独的函数,但我更喜欢在find_if中使用它。即,

include <locale>
std::locale loc;
if ( find_if(field_name.begin(), field_name.end(), isalpha(*this_iterator,loc) == field_name.end() )

问题:有没有办法this_iterator引用当时的迭代器?

在 C++11 中,您可以按照 Timo 的建议使用 lambda 或 std::bind() ,如 std::bind(isalpha, std::placeholders::_1, loc) .

在 C++11 之前,您可以改用std::bind2nd()。不过,这有点复杂,因为它需要一个unary_functionbinary_function作为参数,而不是任何旧的函数对象。我们可以创建一个使用 std::ptr_fun() ,尽管出于某种原因我们需要明确告诉它模板参数是什么。我们需要使用 std::isalpha() 而不是 isalpha() 来获取启用区域设置的版本。所以完整的表达式看起来像

std::bind2nd(std::ptr_fun<char, const std::locale&, bool>(std::isalpha), loc)

不用说,C++11版本要简单得多。


顺便说一句,如果您使用的是 C++11,那么您可以使用 std::any_of(...) 而不是 std::find_if(...) == foo.end() .它的行为应该相同,但可读性稍高。

在 C++11 中,您可以使用 lambda:

if (std::find_if(field_name.begin(), field_name.end(),
                 [&loc](char c)
                 {
                   return isalpha(c, loc);
                 }) == field_name.end())
{
  ...
}

在 C++11 之前,您可能必须使用 boost::bind 或 boost::lambda 之类的东西来实现相同的功能。

在 C++11 之前,您可以使用覆盖 () 运算符的对象包装isalpha(),然后将其用作谓词,如果您不想使用 std::bind...() 或 boost,例如:

#include <locale>
struct isalphaloc
{
    const std::locale &_loc;
    isalphaloc(const std::locale &loc) : _loc(loc) {}
    bool operator(const char c) const
    {
        return isalpha(c, _loc);
    }
};

.

std::locale loc;
if ( find_if(field_name.begin(), field_name.end(), isalphaloc(loc)) == field_name.end() )

最新更新