5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Boost Concept Check Library (BCCL)でインターフェイスを実装する

Posted at

前回述べたように、BCCLを用いればある型のシグネチャを制限する事ができる。
つまりある型Tのインスタンスvar

std::sort(var.begin(), var.end());
int N = var.size();

のような"使い方"(signature)が可能である事を明示的に要請する事ができる。
これはソートが安全に実行できる事を保証するのではなく、
.begin().end()なるメンバーを持っていて、
std::sortの引数の型として適切な型を返す事を保証する。
つまり型演算だけを実行する。

今回はごく簡単なシグネチャを要請するコンセプトチェッククラスを作成する。

たとえばある値を参照でもらって中身を書き換える関数を考えよう。
そのものを書き換える場合(inplace)と、
元のをそのままに別のインスタンスへ変更したものを書き換える場合(outplace)
の両方が実装していてほしいとする。

T val1, val2;
f(val1); // inplace
f(val1, val2); // outplace

みたいに使えると 仮定して
このシグネチャを利用したコードを実装するとしよう。
この仮定をfに要請するにはどうすればいいか?

純粋仮想関数を使用する

まずはコンセプト使わずにOOPのインターフェイスを利用する。

template <class Val> struct TwoWayFunc {
  virtual void operator()(Val &) = 0;
  virtual void operator()(const Val &, Val &) = 0;
};

このインターフェイスクラスをfに継承させればいい。

確かにfを自分が定義するならば問題ない。
しかしジェネリックなライブラリを作成する場合、
このfは一般にライブラリの外部でライブラリのユーザーが定義する関数である。
また複数の別個のシグネチャを仮定する事ができない。

コンセプトを使用する

コンセプトチェッククラスを定義する

template <class Func, class Var> struct TwoWayFunc{
private:
  Func f; // 実際にインスタンス化する必要はない
  Var v; // 同上
  static const Var &cv; // constの引数にする場合

public:
  BOOST_CONCEPT_USAGE(TwoWayFunc) {
    f(v);
    f(cv, v);
  }
};

これだけで十分である。
このクラスを用いて、ジェネリックなアルゴリズムを実装する際に、

template<class Func, class Var>
void generic_algorithm(){
  BOOST_CONCEPT_ASSERT((TwoWayFunc<Func, Var>));

  Func f(...);
  Var var;
  ...
}

のようにBOOST_CONCEPT_ASSERTを用いて要請すればいい。
これで上述したシグネチャが使えない場合、コンパイル時にBOOST_CONCEPT_ASSERTの所でエラーとなる。
実際のアルゴリズムの最中でエラーとなるわでないので、
ライブラリの使用者に(ライブラリの実装ミスでなく)Funcの型が問題なのだと報せられる。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?