
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ランキング
-
VC++で文字列から任意の文字を...
-
なぜ、C++の標準ヘッダをインク...
-
VxWorks 6.4ソケット接続につい...
-
C++での <iostream.h>と<iostre...
-
プログラミング
-
JPEGやPNGが読めるLoadImage関数
-
C++ 数値データファイルから2次...
-
listをvectorにコピーするときに
-
C言語の構造体についてです。
-
自作ライブラリを作成していて...
-
CStringとString
-
gccでコンパイル時のエラー
-
switch文のエラーについて
-
VHDLのsignedとunsignedの違いは?
-
snprintfが使用できない。
-
std::map の const 修飾について
-
C++コンパイラーのincludeのエ...
-
#defineの使い方について
-
Aの値からBの値を除するとは??
-
「Aに対するBの割合」と「Aに対...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VC++で文字列から任意の文字を...
-
なぜ、C++の標準ヘッダをインク...
-
switch文のエラーについて
-
VxWorks 6.4ソケット接続につい...
-
gccでコンパイル時のエラー
-
iostream インクルード時に発生...
-
#include "fstream.h"
-
【C++】ヘッダ内でstringを格納...
-
#defineの使い方について
-
構文エラーが出ているのですが...
-
C言語のポインターで詰まっている
-
std::map の const 修飾について
-
C++での <iostream.h>と<iostre...
-
enumの値から定義名を文字列化...
-
MingwでC++のソースがコンパイ...
-
違い
-
VC++で
-
C++で日本語の処理がしたいです
-
継承されたABのクラスのポイン...
-
C++でShowCursorを使いたい。
おすすめ情報