2016-05-09 8 views
10

constの正確さを維持しながら、const_castを以下のように取り除く良い方法はありますか?std :: setを呼び出すときにconst_castを避けるset <Type*> :: find

const_castを指定しないと、以下のコードはコンパイルされません。 set::findは、セットのキータイプへのconst参照を取得します。したがって、渡されたポインタ値を変更しないことが保証されます。しかし、ポインタが指しているものを変更しないことについては何も保証していません。

class C { 
public: 
    std::set<int*> m_set; 

    bool isPtrInSet(const int* ptr) const 
    { 
     return m_set.find(const_cast<int*>(ptr)) != m_set.end(); 
    } 
}; 
+0

'bool'を返す関数でイテレータを返していますが、このコードは現在コンパイルされていません。 'return m_set.find(const_cast (ptr))!= std :: cend(m_set);'を使用することを意味しましたか? – user2296177

+0

ありがとうございました。ありがとう – Danra

+0

'std :: find'が助けになります。私は彼らが 'std :: set'境界で対数的に動作するように部分的に専門化しているのだろうかと思います。 – bipll

答えて

3

はいです。

C++ 14では、int const*と指定した独自のコンパレータを使用して、を使用することができます。これにより、キーを任意のタイプと比較できるのfind()が有効になります。これに関連するSO questionを参照してください。ここにJonathan Wakely's explanationがあります。

0

あなたがconst int* Sを保存したい場合は、const int*秒を格納します。 int*を代わりに保存したい場合は、そのようにしますが、そのように混在させることはできません(少なくとも、すでに使用したハックなしではできません)。

1つを選択して貼り付けます。

+6

intを* some *メソッドで変更する必要があるので、 'set 'が必要です。しかし、他のいくつかのメソッドはintを変更しないことが保証されています。これらのメソッドのインタフェースでこの約束を伝えるのはいいでしょう。この例では、これはパラメータ 'const int *'を宣言することによって行われます。 – Danra

+3

@Danra:あなたの 'const_cast'はうまく見えます。 –

+0

@ダンナ私はあなたの論理を理解していないのですか?メソッドがconstとマークされている場合、 'm_set'は変更できません。 'const':' int * const ptr'の配置を変更すると、コンパイラのエラーはなくなります。 –

0

constの正確性を維持しながら、下記のconst_castを回避する良い方法はありますか?

私が提案しようとしていることが「良い方法」となるかどうかはわかりません。しかし、あなた自身がセットの内容を反復処理しても構わない場合は、const_castを避けることができます。これは、O(log(N))操作からO(N)操作へと変換できるものであることに留意してください。

bool isPtrInSet(const int* ptr) const 
{ 
    for (auto p : m_set) 
    { 
     if (p == ptr) 
     { 
     return true; 
     } 
    } 
    return false; 
} 
+1

const_castを避けるためにO(N)対O(log(N))を支払う人がいますか? – Slava

+1

@Slava、私は誰も話せない。 –

2

なぜこれが不可能なのかの基本的な論理について説明したいと思います。

set<int*>::find(const int*)が合法であるとします。次に、次の操作を実行できます。

set<int*> s; 
const int* p_const; 
// fill s and p 
auto it = s.find(p_const); 
int* p = *it; 

Hey presto! const_castを実行せずにconst int*int*に変換しました。

+1

あなたのロジックがconstとnotを比較した後、constポインタが不正であるか、誰かが 'find_if()'によってこのhocus pocusを作ることができます。かなり畳み込まれた論理imho – Slava