ページ 1 / 1
構造体のlistでの条件比較
Posted: 2013年11月01日(金) 12:51
by spaaaark・∀・
コード:
class A{
int m_a;
int m_b;
std::string m_Name;
};
というクラスをリストで管理する時を考えます。
コード:
std::list<A> Hoge;
/*処理省略*/
Hoge.unique(/*引数*/); // A.m_Nameが同じものを削除
A.m_Nameが同じものを削除しようと思った時に、/*引数*/はどのように与えるといいのでしょうか?
いろんな参考サイトを回りましたが、いまいち理解できないのでこちらで質問させていただきます。よろしくお願いいたします。
Re: 構造体のlistでの条件比較
Posted: 2013年11月01日(金) 13:08
by h2so5
簡潔に書くならこうなります。
m_Nameをpublicにするかアクセサを用意してください。
コード:
Hoge.unique([](const A& a, const A& b){
return a.m_Name == b.m_Name;
});
Re: 構造体のlistでの条件比較
Posted: 2013年11月01日(金) 13:18
by spaaaark・∀・
h2so5 さんが書きました:
コード:
Hoge.unique([](const A& a, const A& b){
return a.m_Name == b.m_Name;
});
引数の中で関数のような比較をするのですか?あと、この[]はlistでオーバーロードされているのでしょうか…。
僕自身見たことのない文法なので引数の中で何をしているか教えてくださると助かります…。すいません。
Re: 構造体のlistでの条件比較
Posted: 2013年11月01日(金) 13:25
by h2so5
それはラムダ式です。簡単にいうと、事前に定義しなくてもその場で関数を作ることができます。
C++の新しい機能ですがVisualStudio2010でも限定的に使用できます。
[]はキャプチャの指定なのでオーバーロードとは関係ありません。
コード:
auto function = [](const A& a, const A& b){
return a.m_Name == b.m_Name;
};
Hoge.unique(function);
こちらの書き方の方がわかりやすいかもしれません。
つまり比較用の関数 function を作ってそれをunique関数に渡しています。
Re: 構造体のlistでの条件比較
Posted: 2013年11月01日(金) 13:27
by usao
ラムダ式使わない なら,
コード:
//こんな関数を用意して…
bool IsEq( const A &lhs, const A &rhs )
{ return ( lhs.m_Name == rhs.m_Name ); }
//それを使う
Hoge.unique( IsEq );
のように書けばよいかと.
あと,リストのデータ並びがunique以前に m_Nameの並び順でソートされてないとうまく削除できないと思います.
Re: 構造体のlistでの条件比較
Posted: 2013年11月01日(金) 18:32
by spaaaark・∀・
なんとなくやりたいことはわかりました。まずソートする前提条件を忘れてました。
それで、関数を条件として引数を渡すということですね。
autoキーワードは作ったときに自動的にboolに置き換えられられる・・・ということでいいですね。
このstring型のメンバ変数でソートする方法は自分で調べてみようと思います。
ただ気がかりなのは、このラムダ関数の引数でホントに隣同士の値を比較できるのでしょうか?
Re: 構造体のlistでの条件比較
Posted: 2013年11月01日(金) 18:47
by h2so5
spaaaark・∀・ さんが書きました:
autoキーワードは作ったときに自動的にboolに置き換えられられる・・・ということでいいですね。
違います。このautoは戻り値の型ではなく、ラムダ式の型を推論しています。
boolに置き換えるとコンパイルできません。
spaaaark・∀・ さんが書きました:
ただ気がかりなのは、このラムダ関数の引数でホントに隣同士の値を比較できるのでしょうか?
疑問点がよく分からないです...
Re: 構造体のlistでの条件比較
Posted: 2013年11月01日(金) 19:30
by spaaaark・∀・
推論しているということは…実際に使うときに型を決める…という事ですか?
後半のは0,1,2,3...とあったときに、片方に0,1,2...と入ると、もう片方にほんとに
1,2,3...と比較する次の要素が参照渡しされるのか、という疑問です。
それとも何か勘違いしているのでしょうか…?
Re: 構造体のlistでの条件比較
Posted: 2013年11月01日(金) 19:58
by h2so5
型推論はコンパイル時です。
ラムダ式の引数に何が渡されているかは、こんなコードで分かりますよ。
コード:
#include <iostream>
#include <list>
using namespace std;
int main() {
list<int> numbers;
for (int i = 0; i < 10; ++i) {
numbers.push_back(i);
}
numbers.unique([](int a, int b){
cout << a << ", " << b << endl;
return a == b;
});
return 0;
}
Re: 構造体のlistでの条件比較
Posted: 2013年11月01日(金) 21:31
by spaaaark・∀・
うお、なんでかよく分からないけど連番で引数が渡されてる。すごい。
http://ideone.com/Yykdmo
autoは戻り値から推測してコンパイル時に型を決める…という考えでいいのでしょうか?
Re: 構造体のlistでの条件比較
Posted: 2013年11月02日(土) 11:49
by ぼずお
昨日チャットで話してたのでちょっとフォロー
[ラムダ式 C++ ]でググったら出てきました。
http://d.hatena.ne.jp/faith_and_brave/2 ... 1228989087
(const A&, constA&)を引数にとり boolを返すラムダ式の記述は以下のようです。
もし最初からこのように記述されていたらしっくりきたでしょうか?
コード:
[](const A& a, const A& b) -> bool {
return a.name == b.name;
}
戻り値は推論によって省略できるとあります。
コード:
[](const A& a, const A& b) {
return a.name == b.name;
}
省略した場合、
コード:
[](const A& a, const A& b) -> decltype(a.name == b.name) {
return a.name == b.name;
}
とコンパイラに解釈され、(a.name==b.name)の部分は比較演算の結果としてboolになります。
文から型を推定するというdecltype()というのが出てきましたが、私も初めて知りました。
知りたい場合はググってみてくださいw
細かいところ違ってたらすみません。
Re: 構造体のlistでの条件比較
Posted: 2013年11月03日(日) 08:38
by spaaaark・∀・
リンクありがとうございます!
戻り値から推測するのじゃなくて、省略されたdecltype関数の引数に戻り値と同じものがパラメータとして渡されてたんですね!
1つ目のコードと解説で理解できました!ありがとうございました><
Re: 構造体のlistでの条件比較
Posted: 2013年11月03日(日) 10:39
by h2so5
decltypeは関数ではありません。
Re: 構造体のlistでの条件比較
Posted: 2013年11月03日(日) 18:12
by spaaaark・∀・
あ…、型指定子だったんですね、失礼しました。