template<typename InputIterator, typename Predicate>
inline InputIterator
find_if(InputIterator first, InputIterator last, Predicate pred, input_iterator_tag)
{
while (first != last && !bool(pred(*first)))
++first;
return first;
}
我在GCC 4.7.0附带的C ++标准库的实现的源代码中遇到了this snippet。这是输入迭代器的find_if
的特化。我清理了前导下划线,使其更具可读性。
为什么他们在谓词上使用bool
强制转换?
答案 0 :(得分:31)
原因是只写!pred(*first)
可能会导致调用过载的operator!
,而不是调用explicit operator bool
。
有趣的是,此措施是针对pred
采取的,但仍可在提供的实施中选择过载的operator&&
。 <{1}}需要更改为first != last
以防止此过载。
答案 1 :(得分:12)
该标准仅要求谓词可用
可以转换为bool
的上下文。想必,
“谓词”对象可以具有operator bool
函数,
哪个做了正确的事,以及一个operator!
函数
一些完全无关的东西。 (当然,那太可怕了
设计,但标准要求库作为
指定,无论用户代码有多糟糕。)所以g ++
转换为bool
,然后对其结果使用!
转换(只有内置运算符才能应用)。
答案 2 :(得分:2)
在C ++标准中,相对于谓词
编写换句话说,如果算法将Predicate pred作为其参数 首先作为它的迭代器参数,它应该在 构造pred(* first)从上下文转换为bool
单词“contextly converted to bool”意味着即使一个类定义了一个转换函数,它将类的对象转换为bool作为显式运算符,也应该应用它。考虑一个上下文转换为bool
的示例#include <iostream>
struct A
{
explicit operator bool () const { return true; }
};
int main()
{
if ( A() )
{
std::cout << "Here is a contextual conversion to bool" << std::endl;
}
}
因此,在C ++标准引用的上下文中,我没有看到编写表达式
的任何意义first != last && !bool( pred(*first ) )
写
就足够了first != last && !pred(*first )
这里的pred在上下文中被转换为bool。