2

コンテキスト: C++03 のみ + ブーストの使用が許可されています

と同じ問題を提起したい

演算子を使用して述語関数を否定する方法 ! C ++で?

...しかし、オーバーロードされたブール述語を使用すると、次のようになります。

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

単一の を定義することは不可能であるため、明らかに、MyPredicateから派生できません。std::unary_functionargument_type

目的は、次のような読み取り可能な構文で、range adaptersMyPredicateの引数として使用することです。

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;
}

演算子 && および || に注意してください。同様に、このトリックの恩恵を受けることができます。

4

2 に答える 2

1

あなたはこれを行うことができます:

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

于 2013-10-18T16:08:30.407 に答える