enum enumBType {
EN_A = 0,
EN_B,
EN_O,
EN_AB,
};
struct person_t {
long lNumber;
enumBType bType;
int age;
int zipCode;
};
int main() {
person_t personAry[10] = {
{ 123456, EN_A, 20, 5300001 } ,
{ 123457, EN_B, 19, 5300050 } ,
{ 123458, EN_B, 22, 4000010 } ,
{ 123459, EN_O, 30, 6310001 } ,
{ 123460, EN_AB, 18, 7300123 } ,
: // 省略
};
// ※1 構造体person_t型の配列personAryをvectorに変換
std::vector<person_t> vPerson( ※1 );
// std::vector<person_t> vPerson( personAry[0], personAry[10-1] ); NGだった
// ※2 構造体person_tのある要素が存在するかを調べたい
std::vector<person_t> it = std::find( vPerson.begin(), vPerson.end() , 123458 );
if ( it != vPerson.end() ) {
printf("find! \n");
}
}
// C++11
上記サンプルソースにて、2点質問があります。
※1
構造体配列をvectorに変換はできない?いちいちpush_backするしかないんでしょか?
※2
アルゴリズムのfind等を使おうとする場合、構造体にoperatorを作らなきゃ駄目?
(確かに何のキーで検索するのか見えないので要るような気がしますが、イマイチわかりません)
C#やVBばっかり触っててC++のテンプレートクラスやら何やらが全然解っていません。
これこれ、こうだよ と分かる方いましたらご教示ねがいます。
No.2ベストアンサー
- 回答日時:
※1
C++11 なら std::begin とか std::end を使って
std::vector<person_t> vPerson(std::begin(personAry), std::end(personAry));
でできないかな? まあ, 今の場合そもそも配列作らんでもいいよなって話だけど.
※2
std::find には述語を取るバージョンがある. 但し返り値の型に注意 (面倒くさければこの場合 auto で OK だが).
なるほど既存配列のコンテナからイテレータ出せば良かったのかな、と理解しました
std::begin()自体今知ったとこですが。
2についても大体分かりました。
複雑な条件下であれば関数オブジェクトやっぱoperator作るのが一番分かりやすそうです。select from~ってクエリみたくできねぇかな、と必死こいて考えていましたが・・・
一応2について以下の2種類の方法で出来るというのを確認したので
今後この質問を参照する人の為にもここに記載させてもらいます。
// 関数オブジェクト(ワンライナーで済ます)
long lvalue = 123457;
enumBType evalue = EN_B;
// auto it = ~でも良い
std::vector<person_t>::iterator it = find_if(vPerson.begin(), vPerson.end(), [](person_t &t) { return ( (t.lNumber == lvalue) ); } );
// 関数オブジェクト
struct myNumber {
long _number;
myNumber( const long& _l) {
_number =_l;
}
bool operator() (const person_t& patt) const {
return ( _number == patt.lNumber );
}
};
std::vector<person_t>::iterator it2 = find_if(vPerson.begin(), vPerson.end(), myNumber(123460) );
// 単純なoperator作っとく
struct person_t {
long lNumber;
enumBType bType;
int age;
long zipCode;
operator long() {
return lNumber;
}
};
std::vector<person_t>::iterator itr = find(vPerson.begin(), vPerson.end(), 123460 );
まぁ速い遅い考えるともっとしっかり作るべきですが。
No.4
- 回答日時:
[](person_t &t) { return t.lNumber == lvalue; }
は、[&]とかにしないと駄目じゃないかな。
[=]だとエラーになりますね。具体的にコピーするような使用例も思いつかず
大体参照だけの[]ないし[&]くらいしか使わんだろう、みたいな勝手な想像があります。
このあたりは私の勉強不足もあるので、また詰まったら質問させてください。
No.3
- 回答日時:
補足だけ.
まずラムダを使うなら引数は
[](const person_t &t) { return ( (t.lNumber == lvalue) ); }
のように const を付けておく方が親切. ところでこの括弧はなんのためにあるんだろう.
それから関数オブジェクトでいくなら (当然このクラスにしか使わないだろうから) person_t のネストクラスとして作る方がいいと思う (myNumber って名前もどうだろうか) し, 変換演算子も
operator long() const { /* ... */ }
のように const を付けた方がいいと思う.
>のように const を付けておく方が親切. ところでこの括弧はなんのためにあるんだろう.
long lvalue = 123457;
enumBType evalue = EN_B;
( (t.lNumber == lvalue) && (t.bType == evalue) ) のようにしようかな、として質問内容と齟齬ができてしまうので
消した後の残骸です。
その他、まぁ名前は適当なので置いといてください。
myNumberどころかenumなのにbTypeってなんだよプリフィクスおかしいだろとかなっちゃうので
No.1
- 回答日時:
*1
personAry[0] は、personAry[0]の場所ではなく、その構造体そのものが「値」となっています。
personAry[10-1] も、personAry[10-1]の場所ではなく、その構造体そのものです。
それに対して、std::vector(開始,終了)形式のコンストラクタで求められているのは「開始の場所(イテレータやポインタ)」と「終了の場所」です。
C#やVBを知っているのなら。
C++では、structもclassも「値型」です。「参照型」ではありません。
「参照型」に相当するのはポインタです。
*2
person_t は構造体で、 123458 は 整数です。
型がまったくちがう(doubleとintのような暗黙の変換も存在しない)ので「同じ」になるわけがありません。
例えるなら
並んでいる自動車を指差して、「あの中から、リンゴと同じ自動車を探してきてください」と言うようなものです。
このあたりはC#やVBでも同じでは?
> テンプレート
最近のC#,VBには「ジェネリクス型」というのがあるかと思います。
対応させるなら、あれです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
CString型からdouble型への変換
C言語・C++・C#
-
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
構造体のメンバをfor文で回したい
C言語・C++・C#
-
-
4
構造体配列内の文字列検索のよい方法を教えてください
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
switch文のエラーについて
-
空ENTERの判別
-
std::wstringのメモリリークに...
-
構文エラーが出ているのですが...
-
LinuxのQtに関する質問です。
-
コーディング
-
リモートデスクトップの接続元I...
-
CStringとString
-
gccでコンパイル時のエラー
-
Visial C++おけるπの使い方
-
2重の(?)の#include
-
なぜ、C++の標準ヘッダをインク...
-
_tcscat がうまくいきません(V...
-
uniqueの使い方について
-
C++ 文字列とポインタ、STL::ma...
-
【C++】ヘッダ内でstringを格納...
-
C++ std::threadを引数で受け取...
-
#include "fstream.h"
-
C++でShowCursorを使いたい。
-
C言語の漢字のホルダーは、chdi...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
switch文のエラーについて
-
構文エラーが出ているのですが...
-
なぜ、C++の標準ヘッダをインク...
-
gccでコンパイル時のエラー
-
空ENTERの判別
-
【C++】ヘッダ内でstringを格納...
-
snprintfが使用できない。
-
enumの値から定義名を文字列化...
-
#include "fstream.h"
-
C++で、テキストファイルを一行...
-
std::wstringのメモリリークに...
-
C++での <iostream.h>と<iostre...
-
VC++で文字列から任意の文字を...
-
#defineの使い方について
-
wstringの主力
-
vc++の使い方について
-
std::map の const 修飾について
-
string型のフォーマット書式指...
-
構造体配列のvectorへの変換と...
-
指定した文字を削除したい
おすすめ情報