2016-05-04 13 views
2

私はvectorやpairのような標準的なコンテナをテンプレート引数としてカスタム型を使って作業しています。テンプレート型パラメータのC++ const

std::vector<const std::pair<const customType, const double>> 

ハッシュ()演算子と比較演算子==と<が定義されています。ほとんどの時間、これらのテンプレートの種類はのように、const修飾されています。

partial_sort_copy、partial_sort、eraseなどの標準ライブラリ関数にこのような値を渡すと問題が発生します。何らかの理由で、これらの関数は最終的には与えられた型の代入を試みますが、最終的にはconstのためにコンパイルに失敗します。

ベクターとペアのテンプレートタイプにconstをキャストする方法はありますか?すなわち、キャストvector<const myType>~vector<myType>

ありがとうございます。

EDIT:最小のサンプルコードが衝突しました!

// Non-working code: 
std::vector<const std::pair<const int, const double>> list{ { 3, 3. }, { 2, 2. }, { 1, 1. }, { 0, 0. } }; 
std::partial_sort(list.begin(), list.begin() + 2, list.end(), [](const std::pair<const int, const double>& x, const std::pair<const int, const double>& y){ return x.first < y.first; }); 

// This works, actually: 
std::vector<std::pair<int, double>> list{ { 3, 3. }, { 2, 2. }, { 1, 1. }, { 0, 0. } }; 
std::partial_sort(list.begin(), list.begin() + 2, list.end(), [](const std::pair<int, double>& x, const std::pair<int, double>& y){ return x.first < y.first; }); 

標準ライブラリが気に入らないコードについて教えてください。

+1

おそらく、const以外の値のconst値を使用してください。おそらくADLの利用可能な 'swap'を定義するのが助けになるかもしれませんが、' std :: pair'をサブクラス化する必要があります。これは 'std'に何かを定義するのは良い考えではないからです。 – bipll

+0

あなたの答えに感謝します。私はADLを調べます。 – jvier

+0

@bipll std名前空間で 'swap'や' hash'のような関数のオーバーロード/テンプレートを定義することはまったく認められています。 – Johan

答えて

3

このようなconst型のコンテナは、未定義の動作です。 std::vector<const T>はアロケータ型としてstd::allocator<const T>を使用し、アロケータの要件では、値型は非constオブジェクト型でなければならないと言います。

はしても無視している...

ベクトルとのペアのためのテンプレートタイプにconstsを追い出す方法はありますか?すなわち、キャストvector<const myType>~vector<myType>。一般some_template<T>some_template<const T>

あなたがそれらの間をキャストすることはできませんので、全く関係のないタイプです。 const some_template<T>およびsome_template<T>とは異なり、有効な変換はありません。

したがって、constオブジェクトのベクトルの使用をやめてください。代わりに非constオブジェクトのconstベクトルを使用してください。

+0

Hmmm。それはついに何かです。では、そのようなconst制約を、その振る舞いが定義されていない場合、テンプレート化された型で使用することを許可するのはなぜですか? 'const myType const *'は有効な型ですが、ベクトル型のためにそれを使用することは、複製されたconst修飾子とみなされることにも気付きました。これは何とか私の記載された問題に関連していますか?ありがとう! – jvier

+1

@jvier 'const T *'と 'T const *'は同じ型です。代わりに 'const T * const'(星の後の' const'に注意してください)を意味するでしょう。 – milleniumbug

+1

@jvier "未定義の振る舞い"は、あなたが許可していないことを意味しますが、コンパイラは警告メッセージを表示しません。 –

関連する問題