C ++ std
命名空间包含辅助函数std::not1
和std::not2
。它们分别采用一元或二元谓词仿函数,并分别返回std::unary_negate
或std::binary_negate
谓词。
我想知道是否应该使用一些模板魔法来实现
template<typename Predicate> inline
enable_if_t<is_unary_predicate<Predicate>::value, unary_negate<Predicate> >
not_(Predicate const&pred)
{ return unary_negate<Predicate>{pred}; }
template<typename Predicate> inline
enable_if_t<is_binary_predicate<Predicate>::value, binary_negate<Predicate> >
not_(Predicate const&pred)
{ return binary_negate<Predicate>{pred}; }
区分传递的参数pred
以返回适当的谓词。当然,有一些奇怪的情况,传递的对象pred
有两种类型的运算符(一元和二元),当这不起作用,但这些可以在不使用这个辅助函数的情况下处理。
答案 0 :(得分:9)
在没有C ++ 11功能的情况下计算出正确的过载并非完全无足轻重。当设计STL并且提出这些功能对象时,甚至没有编译器能够编译这些功能中的一些。结果,一些功能比原本更难使用。例如,创建data.json
函数完全可行(std::not_()
是不可能的,因为std::not()
恰好是替代令牌,因此不是{ta}可行的功能名称)。也就是说,答案是:它主要是历史性事故。
在函数重载的部分排序规则仍然相当混乱的时候,很有可能提出not
和std::not1
。 STL的主要提议是在1994年或1995年完成的(我无法在How do I download a file over HTTP using Python?中快速找到它)。如果响应STL提案实际更改了过载规则,我不会感到惊讶。
也就是说,在其他人加快速度并开发这些接口的改进版本之前,花了几年的时间。 mailing archive带领着这些发展。
关于实现魔法,创建一个与各种arities一起使用的std::not2
函数实际上可能非常简单:
not_
实际上,这几乎就是在上次会议上被评为C ++工作文件Boost的内容。这是一个C ++ 11的公式,但道德等价可以用早期版本的C ++完成,只需扩展每个支持的arity的函数调用操作符(显然,没有完美的转发)。
答案 1 :(得分:2)
2013年有这样的提案:N3699 A proposal to add a generalized callable negator。这已经持续了一段时间(最新版本是N4022)并且看起来像should make it into the second Library Fundamentals TS;它出现在Library Fundamentals TS 2 draft n4564中的 func.not_fn 部分。
标准中存在not1
和not2
的原因是它们已经存在了相当长的一段时间,因为在存在支持单个否定符所必需的元编程技术之前。