2011-12-27 7 views
0

式テンプレートを作成しようとしていますが、解決方法がわからない問題が発生しました。私はC++のテンプレート:完全なガイドを読んだことがありますが、彼らはこの質問に対処していないようです。式テンプレート内の非const式クラスが必要です

例として、標準の集合演算交差、和集合、否定、xor、差などを持つ集合型setの式テンプレートを考えてみましょう。これらの関数はすべてイテレータに関して効率的な実装をしています。私は式テンプレートのクラスにイテレータのようなインターフェイスを持たせたい。例えば、

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のですが、式を評価するために私がする必要があり値を繰り返し(++val)、これらは非constです。 set::operator = (set_expr &)を非constとして宣言することはできません。なぜなら、一時変数は非constパラメータをバインドしないからです。私はoperator =のconst-nessを投げ捨てることができましたが、それは正しい解決策のようには感じません。

私の例では、問題を明確にするのに十分な詳細がないため、わかりやすく説明します。

編集:ここにいくつかの詳細があります。 set_expr_unionset_expr_intersectionが上記のインタフェースを持っているとします:operator ++,valおよびoperator bool。また、私は

template<class T> 
class set_expr 
{ 
    T t; 
    ...; 
} 
などTは set_expr_unionの一つであることを意図している

、およびset_exprt++, 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)); 
} 

本当に、オペレータからの戻り値に対応する一時的です。

さて、私はset3 = set1 & set2のようなもので、使用する

class set 
{ 
    ...; 

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

を検討してください。

これは、書きたいコードの種類です。

+1

一時ファイルは、必要でない限り、 'const'である必要はありません。あなたが働きかけようとしている表現の例を見せてもらえますか? –

+1

これらの問題を回避するために、[Boost.Proto](http://www.boost.org/libs/proto/)の上に式テンプレートを書くことも検討してください。 – ildjarn

+0

これはむしろあいまいです。一時的なものは常にconstではありません。'set'は' std :: set'のような何らかのコンテナであると仮定すると、非constイテレータ実装も必要です。大部分の状況で 'return(bool)i;'や 'const_cast'のようなことをしてはいけません。 – AJG85

答えて

1

解決策の1つは、あなたの設定式を構築可能で割り当て可能にすることです(比較的軽量であれば大きな問題ではありません)。集合代入演算子では、集合式のコピーを作成し、そのコピーに対して反復処理を行います。

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に移動し、移動セマンティクスにまで読んでみてください。

+0

こんにちはMarkus、返信いただきありがとうございます!これはまさに私がやったことです、 'operator ='引数を非参照にすることです。そして、C++ 11の移動セマンティクスに関するヒントをお寄せいただきありがとうございます。 –

関連する問題