0

抽象テンプレートクラスがあります

template <typename T>
class Predicate1
{
  public:

    Predicate1();

    virtual ~Predicate1();

    virtual bool operator() (const T item) const = 0;
};

実装

class Pred : public Predicate1<string>
{
  public:

    virtual bool operator() (const string item) const;
};


bool Pred::operator()(const string item) const
{
  return item == "";
}

filter述語を取るメソッドを持つテンプレートクラス:

template <typename T>
class TList : public boost::enable_shared_from_this<TList<T> >
{
  public:

    typedef boost::shared_ptr<const TList<T> > List;

    const List filter(const Predicate1<T>& p) const;

    ...
};

次に、次のようにフィルターを使用します。

int main(int argc, char *argv[])
{
  const TList<string>::List l1 = ...;

  const TList<string>::List l2 = l1->filter(Pred());
}

これは問題なく動作します。ただし、ファンクターを無名関数に置き換える方法がわかりません。私が試してみました:

const TList<string>::List l2 =
  l1->filter([] (const string item) -> bool { return item == ""; });

匿名関数は、私が理解している限り、ファンクターの()演算子と同じシグネチャを持っているので、機能するはずです。代わりに、コンパイラエラーが発生します。

error: no matching function for call to ‘TList<std::basic_string<char> >::filter(main(int, char**)::<lambda(std::string)>) const’
note: candidate is: const TList<T>::List TList<T>::filter(const Predicate1<T>&) const [with T = std::basic_string<char>, TList<T>::List = boost::shared_ptr<const TList<std::basic_string<char> > >]

それで、どういうわけかタイプは互換性がないように見えます、しかし私が何かを見落としたかどうか、または私が間違っていることを理解していません。filterつまり、署名付きの無名関数を(のみ)受け入れることができるように、メソッドを宣言するにはどうすればよいですか?

const string -> bool

または、一般的にconst T -> bool

4

1 に答える 1

5

独自のインターフェイスクラスを作成する代わりに、次を使用しますstd::function

const List filter(const std::function<bool (const T)>& p) const;

std::functionラムダとファンクターからのコンストラクターがあるので、引き続き使用できますPred

于 2013-02-01T12:17:58.373 に答える