宜しくお願いいたします。
行いたいことはvectorコンテナでmapのpairのような振舞いさせたくて
下記のような実装を行い目的は果たせているのですが、もっとエレガントに
描けないでしょうか、ご教示お願いいたします。
find_if()を使ったらできそうなのですが力が無くてできません(´~`;)トホホ・・
環境:WinXP/VS2005 Express
/*
構造体の特定の要素を比較し、等しければ同じ位置にある他の要素を取得する
*/
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct tagStructure {
int count;
string yymmdd;
tagStructure( int n = 0, string str = " ) : count( n ), yymmdd( str ){}
};
int main()
{
char buff[32];
string str;
vector<tagStructure> vec;
tagStructure tagst;
for(unsigned int i = 0; i < 4; ++i) {
tagst.count = i;
_itoa_s( static_cast<unsigned int>( i ), buff, sizeof( buff ), 10 );
str = buff;
tagst.yymmdd = str + 日経過;
vec.push_back(tagst);
}
for( unsigned int i = 0; i < vec.size(); ++i )
cout << vec[ i ].count << , << vec[ i ].yymmdd << endl;
static const int magicNum = 3;
vector<tagStructure>::iterator it = vec.begin();
while ( it < vec.end() ) {
if( magicNum == it->count )
cout << it->yymmdd << endl;
++it;
}
return 0;
}
#include <iostream> // cout
#include <string> // string
#include <vector> // vector
#include <utility> // pair
#include <algorithm> // remove_copy_if
#include <functional> // bind1st
#include <iterator> // ostream_iterator
using namespace std;
struct Structure : public pair<int,string> {
Structure(int n) : pair<int,string>(n,") {}
Structure(int n, const string& s) : pair<int,string>(n,s) {}
};
struct neq : binary_function<Structure,Structure,bool> {
bool operator()(const Structure& x, const Structure& y) const {
return x.first != y.first;
}
};
ostream& operator<<(ostream& stream, const Structure& x) {
return stream << x.first << ':' << x.second;
}
int main() {
vector<Structure> vec;
vec.push_back(Structure(1,one));
vec.push_back(Structure(2,two));
vec.push_back(Structure(1,eins));
vec.push_back(Structure(3,three));
vec.push_back(Structure(1,いち));
vec.push_back(Structure(1,壱));
remove_copy_if(vec.begin(), vec.end(),
ostream_iterator<Structure>(cout,\n),
bind1st(neq(),Structure(1)));
}
> mapのpairのような振舞いさせたくて
素直にmapを使えば良いと思うが。。。
> find_if()を使ったらできそうなのですが
↓使ってみた。
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
struct Structure {
int count;
std::string yymmdd;
Structure( int n = 0, std::string str = " ) : count( n ), yymmdd( str ) {}
};
class CountEquals {
const int& count;
public:
CountEquals( const int& n ) : count( n ) {}
bool operator()( const Structure& s ) {
return s.count == count;
}
};
const int MAGIC_NUM = 3;
int main ()
{
std::string buff;
std::vector< Structure > vec;
for( int i = 0; i < 4; ++i ) {
std::ostringstream oss;
oss << i;
vec.push_back( Structure( i, oss.str() + 日経過 ) );
}
for( std::vector< Structure >::size_type i = 0; i < vec.size(); ++i ) {
std::cout << vec[ i ].count << , << vec[ i ].yymmdd << std::endl;
}
std::vector< Structure >::iterator pos
= std::find_if( vec.begin(), vec.end(), CountEquals( MAGIC_NUM ) );
if( pos != vec.end() ) {
std::cout << found! << pos->yymmdd << std::endl;
}
else {
std::cout << not found...orz << std::endl;
}
}
επιστημηさん、iijimaさん
お世話になります。
とほほです三日待って下さい脳内で咀嚼します。
関数オブジェクト(ファンクタ)が鬼門になっていて理解力がありません、
「Effective STL」を読み直します
> 関数オブジェクト(ファンクタ)が鬼門
私もはじめて「関数オブジェクト」という用語を見たときは?でしたが、「なんだ戻り値
がbool型の()演算子を定義しているだけじゃんか」と気がついてからは楽になりました。
言葉に惑わされる事なかれ。
関数オブジェクトとかファンクタなんていう用語を知らなくても、演算子の多重定義をし
っかり理解していれば鬼は出ません。
それに加えてテンプレートも勉強すればalgorithmもなんということはありません。
επιστημηさんのは難しそうに見えますが、基本を勉強した後にC++標準ライブラ
リを丹念に調べれば理解できるはずです。
# クラスの継承について十分に理解しているのは前提ですが。
余計なお世話ながらおまけのサンプル↓
// サンプル(1):簡単関数オブジェクト
struct IsEven {
bool operator()( int n ) const {
return n % 2 == 0;
}
};
#include <iostream>
int main()
{
int coll[] = { 0, 3, 2, 1, 4 };
IsEven is_even; // 関数オブジェクト
for( int i = 0; i < sizeof( coll ) / sizeof( coll[ 0 ] ); ++i ) {
std::cout << coll[ i ] << は;
if( is_even( coll[ i ] ) ) { // ()演算子の定義により関数のように使える
std::cout << 偶数 << std::endl;
}
else {
std::cout << 奇数 << std::endl;
}
}
}
// サンプル(2):簡単アルゴリズム関数
// STLのアルゴリズム関数もやっていることはたいして変わらない。
// STLのソースも参照してみたら良いよ。
template < typename T, typename F >
T* find_if( T* beg, T* end, F& func )
{
T* p;
for( p = beg; p != end; ++p ) {
if( func( *p ) ) {
break;
}
}
return p;
}
#include <string>
#include <iostream>
struct Pair {
int count;
std::string str;
Pair( int n, std::string s ) : count( n ), str( s ){}
};
class CountEquals {
const int& count;
public:
CountEquals( const int& n ) : count( n ) {}
bool operator()( const Pair& p ) const {
return p.count == count;
}
};
int main()
{
Pair coll[] = {
Pair( 3, 三 ),
Pair( 4, 四 ),
Pair( 1, 一 ),
Pair( 2, 二 ),
Pair( 0, 零 ),
};
Pair* beg = coll;
Pair* end = coll + sizeof( coll ) / sizeof( coll[ 0 ] );
CountEquals func( 2 );
Pair* pos = find_if( beg, end, func );
if( pos != end ) {
std::cout << pos->count << , << pos->str << std::endl;
}
else {
std::cout << not found. << std::endl;
}
}
iijimaさん、お世話になります
関数オブジェクトに関して、だいぶ理解が深まりました
といいますかiijimaさんが、噛み砕いて説明して下さったことが全てと理解し
単純に考えます。
STLは巧く使うとCの配列に比べメモリー管理も非常に楽でパワフルなのですが
私の場合少し高度なことを行おうとすると大概可読性の低い
何をやってるのか( ゜д゜)ポカーン …なコードか洗練されないものになってしまいます
そのようにならないため、関数オブジェクトやTemplateが使えると使えないのでは
雲泥の差が有るので、是非マスターして、一人前のC++使いになりたいと思います
沢山のサンプルコードありがとうございました。