0

式テンプレートを作成しようとしていますが、解決方法がわからない問題に遭遇しました。C++ Templates: The Complete Guide を読みましたが、この質問に対処していないようです。

例として、(整数の) セット型の式テンプレートを考えてみましょう。これにはset、標準的なセット操作の交差、和集合、否定、xor、差などがあります。これらの関数はすべて反復子に関して効率的な実装を備えているため、式テンプレートが必要です。イテレータのようなインターフェースを持つクラス。例えば、

class set_expr_set
{
  set::iter i;

  set_expr_set (const set &s) : i(s) { }

  operator bool () const { return (bool)i; }
  void operator ++ () { i ++; }
  int val () { return *i; }  
}

次に、式テンプレートクラスset_expr_unionなどがあります。問題は、式テンプレート式に対応して作成されたオブジェクトはすべて一時的であるため、const ですが、式を評価するには、値を反復処理する必要があります ( and を呼び出す++) val、およびこれら非定数です。set::operator = (set_expr &)一時変数は非定数パラメーターをバインドしないため、非定数として宣言することはできません。の const 性を取り除くこともできますoperator =が、それは適切な解決策とは思えません。

私の例には、問題を明確にするのに十分な詳細がありません。喜んで明確にします。

編集:ここにいくつかの詳細があります。上記のインターフェースもあると仮定set_expr_unionします: 、および。また、私が持っているとしますset_expr_intersectionoperator ++valoperator bool

template<class T>
class set_expr
{
  T t;
  ...;
}

ここで、 T はset_expr_unionなどのいずれかであり、のインターフェースset_exprもエクスポートします。t++, val, bool

式テンプレート オブジェクトは、次のようなさまざまな演算子によって生成されます。

template<class T1, class T2>
set_expr<set_expr_intersection>
operator & (const set_expr<T1> &e1, const set_expr<T2> &e2)
{
  return set_expr<set_expr_intersection> (set_expr_intersection (e1.t, e2.t));
}

実際、オペレーターからの戻り値に対応する一時的な部分に問題があります。

では、考えてみましょう

class set
{
  ...;

  template<class T>
  set &operator = (const set_expr<T> &e)
  {
    clear ();
    for (; e; e ++)
      add_element (e.val ());
  }
};

のようなもので使用したいset3 = set1 & set2

これは私が書きたいコードです。

4

1 に答える 1

1

1 つの解決策は、set 式をコピーして構成可能で代入可能にすることです (比較的軽量であれば大きな問題にはなりません)。セット代入演算子では、セット式のコピーを作成し、そのコピーを反復処理します。

template<class T>
set& operator=(const set_expr<T> &e) {
  clear ();
  for (set_expr<T> i = e; i; i++) {
    add_element (i.val());
  }
  return *this;
}

セット式をコピーするとコストがかかりすぎることが判明した場合は、c++11 に移行し、移動セマンティクスについて調べてください。

于 2011-12-30T13:10:46.820 に答える