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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# このプログラミング誰か教えてください 9 2022/04/22 18:50
- フランス語 フランス語文章の構造と意味 1 2022/08/23 16:56
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# このプログラミング誰か教えてください。 2 2022/04/22 18:48
- フランス語 フランス語の意味と構文について 1 2023/03/07 15:28
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
enumの値から定義名を文字列化...
-
linux系OSでC99
-
VC++で文字列から任意の文字を...
-
【C++】複素数で配列を使いたい
-
CStringとString
-
JPEGやPNGが読めるLoadImage関数
-
switch文のエラーについて
-
C++ 数値データファイルから2次...
-
構造体に決められた文字列を入...
-
【C++】ヘッダ内でstringを格納...
-
C++でShowCursorを使いたい。
-
string型のフォーマット書式指...
-
VxWorks 6.4ソケット接続につい...
-
C++で大量のエラーが出る
-
C++のifstreamの使い方
-
Vectorのポインタが入ったvector
-
C++でコンパイルするとwarning...
-
findnext();について
-
Visial C++おけるπの使い方
-
テイラー展開とその精度について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
構文エラーが出ているのですが...
-
switch文のエラーについて
-
enumの値から定義名を文字列化...
-
VC++で文字列から任意の文字を...
-
なぜ、C++の標準ヘッダをインク...
-
空ENTERの判別
-
std::wstringのメモリリークに...
-
C言語からgnuplot呼び出し
-
リモートデスクトップの接続元I...
-
JPEGやPNGが読めるLoadImage関数
-
このプログラミング誰か教えて...
-
プログラミング
-
#include "fstream.h"
-
C++での <iostream.h>と<iostre...
-
std::map の const 修飾について
-
構造体配列のvectorへの変換と...
-
#defineの使い方について
-
VS2019でofstreamが未定義になる
-
指定した文字を削除したい
-
構造体に決められた文字列を入...
おすすめ情報