c++ - 使用运算符!否定重载的 bool 谓词

标签 c++ boost functional-programming

上下文:仅限C++03 + 授权使用boost

我想提出同样的问题

How to negate a predicate function using operator ! in C++?

...但是有一个重载的 bool 谓词,即:

struct MyPredicate
{
    bool operator()(T1) const;
    bool operator()(T2) const;
};

显然,MyPredicate 不能从 std::unary_function 派生,因为不可能定义单个 argument_type

目标是使用 MyPredicate 作为 range adaptors 的参数,具有像这样的可读语法:

using boost::for_each;
using boost::adaptors::filtered;

list<T1> list1;
list<T2> list2;

for_each(list1 | filtered(!MyPredicate()), doThis);
for_each(list2 | filtered(!MyPredicate()), doThat);

当然,任何涉及显式消歧的解决方案在这里都没有意义。

提前谢谢你。

[接受的解决方案]

我使用的是 Angew 解决方案的略微修改版本:

template <class Predicate>
struct Not
{
  Predicate pred;

  Not(Predicate pred) : pred(pred) {}

  template <class tArg>
  bool operator() (const tArg &arg) const
  { return !pred(arg); }
};

template <class Pred>
inline Not<Pred> operator! (const Pred &pred)
{
  return Not<Pred>(pred);
}

template <class Pred>
Pred operator! (const Not<Pred> &pred)
{
  return pred.pred;
}

请注意运算符 && 和 ||同样可以从这个技巧中受益。

最佳答案

你可以这样做:

struct MyPredicate
{
  bool positive;
  MyPredicate() : positive(true) {}

  bool operator() (T1) const {
    return original_return_value == positive;
  }
  bool operator() (T2) const {
    return original_return_value == positive;
  }
};

inline MyPredicate operator! (MyPredicate p) {
  p.positive = !p.positive;
  return p;
}

为了解决您对忘记使用 positive 的担忧,您可以尝试使用包装类的替代方法。

template <class Predicate>
struct NegatablePredicate
{
  Predicate pred;
  bool positive;

  NegatablePredicate(Predicate pred, bool positive) : pred(pred), positive(positive) {}

  template <class tArg>
  bool operator() (const tArg &arg) const
  { return pred(arg) == positive; }
};

template <class Pred>
inline NegatablePredicate<Pred> operator! (const Pred &pred)
{
  return NegatablePredicate<Pred>(pred, false);
}

您还可以添加重载以进行优化:

template <class Pred>
inline NegatablePredicate<Pred> operator! (const NegatablePredicate<Pred> &pred)
{
  return NegatablePredicate<Pred>(pred.pred, !pred.positive);
}

为了解决模板 operator! 的广泛范围可能引起的问题,您可以使用 boost::enable_if 魔法。

关于c++ - 使用运算符!否定重载的 bool 谓词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19453720/

相关文章:

scala - 输入流的迭代器 : How to close the InputStreams?

haskell - 在 Haskell 中评估零函数

c++ - 新建、删除、malloc、free

c++ - WaitForSingleObject 死锁

c++ - boost asio ssl::stream<tcp::socket> 是否支持多个挂起的 http::async_write 调用?

c++ - 将 time_period 转换为 date_period

Javascript:对相邻对象的函数调用?

c++ - 维护一个与 std::map 平行的 std::vector

c++ - 字符到整数的转换?

c++ - 在 cuda 设备代码中使用 boost 等库