struct SomeStructure {
uint64_t value;
uint64_t data;
};
bool operator > (const SomeStructure& v1, const SomeStructure& v2) {
return (v1.value > v2.value);
}
bool operator < (const SomeStructure& v1, const SomeStructure& v2) {
return (v1.value < v2.value);
}
bool operator == (const SomeStructure& v1, const SomeStructure& v2) {
return (v1.value == v2.value);
}
は、次のようなコードで使用されます。
SomeStructure st1, st2;
st1.value = st2.value = 10; // has the same 'value'
st1.data = 20; // but is assigned a different number for the 'data'.
st2.data = 40;
std::set<SomeStructure> TheSet;
TheSet.insert(st1);
TheSet.insert(st2);
はst1
後st2
を挿入しますセットに存在する要素の値を置き換えますか?オペレータ>
と<
のみメンバーSomeStructure::value
に依存するようにオーバーロードされているため、TheSet
にそれらを挿入しながら、上記の例では
は、st2
とst1
両方が同じであると考えられます。しかし、これらのオブジェクトではSomeStructure::data
の値が異なります。したがって、それはTheSet
の既存の要素を置き換えますか、または要素が既に存在する場合は挿入操作を無視しますか?
これらの2つの動作のどちらかを明示的に実施する方法はありますか?
この動作はコンパイラとプラットフォームによって変わりますか?
編集1:
私はちょうどグラムでこれをテストした++コンパイラ(C++ 11を有効にしました)。それは置き換えません。既存の要素を置き換えるためにこれを明示的に実施する方法はありますか?
編集2:
実際には、この動作を「強制」する標準的な方法はありませんが、それはを通じて、単純なハックを使用して行うことができます。このメソッドは推奨されませんが、私はここにそれを提示してみましょう:
この方法は、STD ::設定
template <typename T>
void insert_replace(std::set <T>& theSet, const T& toInsert) {
auto it = theSet.find(toInsert);
if(it != theSet.end())
*((T*)&(*it)) = toInsert;
else
theSet.insert(toInsert);
}
内のメンバ関数insertの代わりに使用する必要があり、上記のコードでなければなりません置き換え:
int main() {
SomeStructure st1, st2;
st1.value = st2.value = 10; // has the same 'value'
st1.data = 20; // but is assigned a different number for the 'data'.
st2.data = 40;
std::set<SomeStructure> TheSet;
insert_replace (TheSet, st1);
insert_replace (TheSet, st2);
for(auto ii : TheSet) {
std::cout << ii.data;
}
return (0);
}
この方法では、出力を与え、私のコンパイラで正常に動作します:40
、代わりの20
。しかし、私は人々がこれは推奨された方法ではないと思うかもしれないと考えています。なぜなら、*((T*)&(*it)) = toInsert;
という行は、イテレータit
が定数ではないと考えてコンパイラを欺くものです。私はこれが唯一の方法であると信じて、交換することによって、std::set
を挿入することができます。私のコードでこのメソッドを使うのはいいですか?将来(たとえ私がそれを文書化しても)問題を引き起こしますか?documentationから
フレンドリーマニュアルを読んでいますか? –
両方を挿入したい場合は、比較関数を変更して、 'value'と' data'の両方をチェックします。それ以外の場合は無視されます。 – Barmar
実際には、 'value'のみに依存することになっています。私のコードでは、既存の要素を新しい要素に置き換える必要があります。しかし、標準の動作の一部ですか?それともコンパイラで変わるのだろうか? –