2009-10-04 4 views
5

私はこのようなテンプレートクラスを持っている:(テンプレートのconst_cast非コンストモディファイアはありますか?

MyClass<const MyObject> mci; 

を私はconst_cast<MyObject*>dataを使用してデータを変更したい:

template<T> 
class MyClass 
{ 
    T* data; 
} 

は時々、私は次のように一定のタイプTを持つクラスを使いたいですなぜMyClassがデータ自体に参照カウントを保持する参照カウントスマートポインタクラスであるかは重要ではありません データは変更すべきではありませんが、スマートポインタ。 )。

Tからconst-nessを削除する方法はありますか?架空のコード:

const_cast<unconst T>(data) 

答えて

11

ここで最も簡単な方法は、参照カウントを変更可能にすることです。あなたはそれがconst_castでどのように動作するかに興味がある場合

しかし、その後、ブーストのremove_constを再実装することは非常に簡単でなければなりません。ここで

template <class T> 
struct RemoveConst 
{ 
    typedef T type; 
}; 

template <class T> 
struct RemoveConst<const T> 
{ 
    typedef T type; 
}; 

const_cast<typename RemoveConst<T>::type*>(t)->inc(); 
+0

remove_constが私にどのように作用するかを説明してくれてありがとう。 – danatel

+3

@danatel:あなたは本当にremove_constを使いたくありません。const値をキャストしてconst値を変更することは、未定義の動作です。 refcount変数に__mutable__を使いたいとします。 –

+0

:-)私は変更可能です。私は自分の問題を解決する必要はありませんでした。問題はイラストのようにそこにありました(オリジナルの記事を読んでください) - 一定性を取り除く方法があるのか​​不思議でした。 – danatel

5

あなたは答えがあります。 const_castは双方向で動作します:

char* a; 
const char* b; 

a = const_cast<char*>(b); 
b = const_cast<const char*>(a); // not strictly necessarily, just here for illustration 

具体的な問題については、可変キーワードを検討しましたか? constメソッド内でメンバ変数を変更することができます。

class foo { 
    mutable int x; 
public: 
    inc_when_const() const { ++x; } 
    dec_when_const() const { --x; } 
}; 
+0

しかし、これはテンプレートクラスです。 Tはconstなものです。問題は、Tからnonconstを作成するにはどうすればいいですか? – danatel

+1

+1ここで答えは不可能です。 – UncleBens

3

あなたはブーストを使用することができた場合は、タイプトレイトライブラリーはそれを行うremove_constメタ関数を提供します。

+0

残念ながら、このプロジェクトではBoostを使用できません。しかし、標準のC++でこれを行う簡単な方法があったなら、誰もremove_constを書くことはありません。したがって、そのような方法はありません。 – danatel

+0

あなたは他の答えをお読みですか? Boostはちょうどmeta-templatedバージョンです。ちょうどconst_castを使用し、それからconstを削除するか、または変更可能です.jumcchellioのように – GManNickG

4

あなたの侵入型ポインタによって管理されるクラスで参照カウントを変更可能にします。これは完全に合理的であり、「論理的な定数」を正確に反映します。つまり、オブジェクトの参照カウントを変更しても、オブジェクト自体の状態の変化は反映されません。言い換えれば、参照カウントは論理的にオブジェクトの一部ではなく、この半無関係なデータを格納するのに都合の良い場所であるだけです。

0

は私のC++ 11 unconst機能templateです。

あなたがそれを使用する場合、あなたはundefined behaviorで遊んでいます。あなたはと警告されましたです。

// on Ubuntu (and probably others) compile and test with               
// g++ -std=c++11 test.c && ./a.out ; echo $?        

template < class T > T & unconst (T const & t) { 
    return const_cast < T & > (t) ; 
} 

// demonstration of use 

struct { 
    const int n = 4; 
} s; 

int main() { 
    unconst (s.n) = 5; 
    return s.n; 
} 
+0

これはもっと簡単で、同じ効果があると思います。テンプレート T&unconst(T const&t){return const_cast (t);} '。 – alfC

+0

ありがとう!それはより簡単で、うまくいくようです。私は 'typename'と' class'の違いが何であるか疑問に思いました。 – mpb

関連する問題