2016-10-16 8 views
1

この質問で私はC++の基本を理解しようとしています。 thisのような、カスタムクラスのベクトル/リストのソートの問題に対する多くの良い答えがあります。すべての例で、ソートに渡されるコンパレータ関数のシグネチャは次のようになります。カスタムクラスのオブジェクトへのポインタを管理するベクトルをソートするコンパレータ

(const ClassType& obj1, const ClassType& obj2) 

このシグネチャはコンパレータ機能に必須ですか?あるいは、次のようなものを与えることもできます:

(ClassType obj1, ClassType obj2) 

私はそれに応じてコンパレータのボディを修正すると仮定します。

最初の署名が必須の場合、その理由は何ですか? constの参照 '&'を使用する理由を理解したい。 私が考えることはconstです。これは、コンパレータ機能が要素を変更できないようにするためです。また、複数のコピーが作成されないようにするためのリファレンスです。

カスタムクラスのオブジェクトへのポインタを含むベクトルをソートするにはどうすればよいですか? (1)または(2)のように(または下記参照)、あるいは両方がうまくいくでしょうか?ソートする vertorはVector型の

である(1)

(const ClassType*& ptr1, const ClassType*& ptr2) 

(2)

(ClassType* ptr1, ClassType* ptr2) 
+0

私はあなたがポインタを比較したいとは思わない?あなたは?配列にオブジェクトへのポインタが含まれていても、おそらくオブジェクトの実際のインスタンスを比較したいと思うでしょうか? –

+0

_ "私はC++の基本を理解しようとしています。私はC++を非常に新しくしています。" –

答えて

0

constがそうあなたがそれらを比較している間、値を変更しないことを知っています。参照は、値を比較しようとしている間に値のコピーを作成したくないためです。コピーできない場合もあります。

最初の例のようになります。これは常に、ベクトルの要素のconst型への参照です。あなたはベクトルを持っている場合は

は、それはいつもだ:だから

T const & left, T const & right 

、Tは、ポインタである、比較のための署名は比較が含まれている場合。

+0

ありがとうございます。あなたはポインタへの参照を渡す必要がありますか? – PHcoDer

+0

私はあなたがstd :: sort http://en.cppreference.com/w/cpp/algorithm/sortのようなsometihngを使用していると思われました。参照を「渡す」ことはありません。参照しているものが参照を取得する場合、参照は自動的に作成されます。 – xaxxon

+0

それでは、どのような署名が必要ですか?問題のタイプ(1)またはタイプ(2)。 – PHcoDer

0
(ClassType obj1, ClassType obj2) 

ほとんどの場合、このシグネチャはコンパレータでも機能します。それが使用されない理由は、オブジェクトが値を渡していることを認識する必要があるため、オブジェクトをコピーする必要があるからです。

これは完全に無駄になります。コンパレータ機能は、そのパラメータの独自のコピーを持つ必要はありません。必要なのは、比較する必要のある2つのオブジェクトへの参照だけです。さらに、コンパレータ機能は、比較しているオブジェクトを変更する必要はありません。それはしないでください。したがって、明示的にconst参照を使用すると、比較関数が誤ってコード化されてオブジェクトを変更すると、コンパイルエラーが発行されます。

これは間違いなく動作しませんが、コピーコンストラクタを削除したクラスの場合です。これらのクラスのインスタンスはまったくコピーできません。まだemplaceをコンテナに入れることはできますが、コピーすることはできません。しかし、彼らはまだ比較することができます。

+0

ありがとうございました!しかし、ポインタのベクトルの場合はどうすればよいでしょうか?コピーの問題はありません。また、constの使用はポインタで意味を成しますか? – PHcoDer

+0

"ほとんどの場合、このシグネチャは動作します。"というタイプはコピーできません。 – xaxxon

+0

単純なポインタの場合は、ほとんど違いがありません。良いコンパイラは、同じインラインコードをコンパイルすることになります。 –

1

This Documentationから探してみることをおすすめします。

それはコンペア機能の署名と等価なければならないことを説明しています。それは、その後、各パラメータが暗黙的に変換可能あるタイプにする必要があることを説明するために行くより正確なので

bool cmp(const Type1& a, const Type2& b); 

イテレータを逆参照して得られたオブジェクトからソート関数に渡します。だから、

あなたのイテレータはstd::vector<ClassType*>::iterator、あなたの引数はClassType*から暗黙的に変換可能する必要がある場合。

あなたがintpointerのような比較的小さなものを使用している場合、私は値によってそれらを受け入れる:

bool cmp(ClassType* ptr1, ClassType* ptr2) // this is more efficient 
0

STLについては本当に特別なものは何もありません。私は2つの主な理由から、少し便利な配列(std :: vector)と、バランスのとれたバイナリ検索ツリーを実装する面倒な作業のために使います。 STLは比較器の標準的な署名を持っているので、すべてのアルゴリズムは '<'操作で動作するように書かれています。彼らは '>'操作やCのqsort()規約を簡単に選択できます。また、必要に応じて独自のテンプレート分類ルーチンを記述することもできます。しかし、すべてが同じ規則を使用するならば、C++を使う方が簡単です。

コンパレータは、コンパレータが比較しているものを変更しないでください。また、参照が値渡しよりオブジェクトに対して効率的であるため、コンパイラはconst参照を受け取ります。単純に整数をソートしたいのであれば(まれに、実際のプログラムで生の整数をソートする必要はありませんが、しばしば演習として行われますが)、値渡しでSTLよりも少し速い独自のソートを書くことができます結果として並べ替えます。

関連する問題