while構文からfor_each構文へ

[戻る]
とほほ 2008/02/27(水) 23:34:42
いつもお世話になります。
下記のソースの
  while( num != vec.size() ) {
  〜省略
  }
この部分をfor_each構文に置き換えたいのですが、ご教示願えませんでしょうか

class ShowTable {
  const int& num;
public:
  ShowTable( const int& n) : num( n ) {}
  void Show( int num )
  {
    vector<ST_TABLE>::iterator pos
      = find_if( vec.begin(), vec.end(), DateEquals( num ) );
    cout << pos->data;
  }
};

グローバルスペースにこの様な関数を定義したらできるような感じがしたのですが
巧く描けませんorz・・・・
環境:WinXP/VS2005 Express

// for_each.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;
struct ST_TABLE {
  int num;
  int data;
  ST_TABLE( int num_ = 0, int data_ = 0) : num( num_ ), data(data_){}
};

vector<ST_TABLE> vec;

class DateEquals {
  const int& num;
public:
  DateEquals( const int& n) : num( n ){}
  bool operator()( const ST_TABLE& s ) {
    return s.num == num;
  }
};

int _tmain(int argc, _TCHAR* argv[])
{
  // データセット
  ST_TABLE st_table;
  vec.push_back(st_table);
  st_table.num = 1;
  st_table.data =10;
  vec.push_back(st_table);
  st_table.num = 2;
  st_table.data =20;
  vec.push_back(st_table);
  st_table.num = 3;
  st_table.data =30;
  vec.push_back(st_table);
  st_table.num = 4;
  st_table.data =40;
  vec.push_back(st_table);
  st_table.num = 5;
  st_table.data =50;
  vec.push_back(st_table);
  st_table.num = 6;
  st_table.data =60;
  vec.push_back(st_table);
  st_table.num = 7;
  st_table.data = 70;
  vec.push_back(st_table);
  st_table.num = 8;
  st_table.data =80;
  vec.push_back(st_table);
  st_table.num = 9;
  st_table.data =90;
  vec.push_back(st_table);
  st_table.num = 10;
  st_table.data =100;
  vec.push_back(st_table);
  
  int num = 1;
  while( num != vec.size() ) {
    vector<ST_TABLE>::iterator pos
      = find_if( vec.begin(), vec.end(), DateEquals( num ) );
    cout << pos->data << endl;
    ++num;
  }
  return 0;
}

επιστημη [HomePage] 2008/02/28(木) 00:35:50
こんなんでいいのかしら。

#include <vector>
#include <algorithm>
#include <iostream>

struct ST_TABLE {
  int num;
  int data;
  ST_TABLE( int num_ = 0, int data_ = 0) : num( num_ ), data(data_){}
};

inline bool operator==(const ST_TABLE& x, const ST_TABLE& y) {
  return x.num == y.num;
}

std::vector<ST_TABLE> vec;

template<typename Container>
class DateEquals {
  Container& container_;
public:
  DateEquals(Container& c) : container_(c){}
  void operator()( const typename Container::value_type& x ) const {
    std::cout << std::find(container_.begin(), container_.end(), x)->data << 
std::endl;
  }
};

int main()
{
  // データセット
  ST_TABLE st_table;
  vec.push_back(st_table);
  st_table.num = 1;
  st_table.data =10;
  vec.push_back(st_table);
  st_table.num = 2;
  st_table.data =20;
  vec.push_back(st_table);
  st_table.num = 3;
  st_table.data =30;
  vec.push_back(st_table);
  st_table.num = 4;
  st_table.data =40;
  vec.push_back(st_table);
  st_table.num = 5;
  st_table.data =50;
  vec.push_back(st_table);
  st_table.num = 6;
  st_table.data =60;
  vec.push_back(st_table);
  st_table.num = 7;
  st_table.data = 70;
  vec.push_back(st_table);
  st_table.num = 8;
  st_table.data =80;
  vec.push_back(st_table);
  st_table.num = 9;
  st_table.data =90;
  vec.push_back(st_table);
  st_table.num = 10;
  st_table.data =100;
  vec.push_back(st_table);
  
  std::for_each(vec.begin(), vec.end(), DateEquals<std::vector<ST_TABLE>>
(vec) );
  return 0;
}

επιστημη [HomePage] 2008/02/28(木) 09:21:36
ちょっといぢった。

#include <vector>
#include <list>
#include <iterator>
#include <algorithm>
#include <iostream>

using namespace std;

struct ST_TABLE {
  int num;
  int data;
};

inline bool operator==(const ST_TABLE& x, const ST_TABLE& y) {
  return x.num == y.num;
}

template<typename Iterator>
class DateEquals {
  Iterator begin_;
  Iterator end_;
public:
  DateEquals(Iterator b, Iterator e) : begin_(b), end_(e) {}
  void operator()( const typename iterator_traits<Iterator>::value_type& x ) 
const {
    cout << std::find(begin_, end_, x)->data << endl;
  }
};

int main() {
  ST_TABLE array[] = {
    {  0,   0 },
    {  1,  10 },
    {  2,  20 },
    {  3,  30 },
    {  4,  40 },
    {  5,  50 },
    {  6,  60 },
    {  7,  70 },
    {  8,  80 }, 
    {  9,  90 },
    { 10, 100 },
  };
  cout << "配列でも:\n";
  for_each(array, array+11,
                DateEquals<ST_TABLE*>(array, array+11) );

  vector<ST_TABLE> vec(array, array+11);
  cout << "vectorでも:\n";
  for_each(vec.begin(), vec.end(), 
                DateEquals<vector<ST_TABLE>::iterator>(vec.begin(), vec.end
()) );

  list<ST_TABLE> lst(array, array+11);
  cout << "listでも:\n";
  for_each(lst.begin(), lst.end(), 
                DateEquals<list<ST_TABLE>::iterator>(lst.begin(), lst.end()) );
}

επιστημη [HomePage] 2008/02/28(木) 09:31:29
悪ノリ ^^;

#include <vector>
#include <list>
#include <iterator>
#include <algorithm>
#include <iostream>

using namespace std;

struct ST_TABLE {
  int num;
  int data;
};

inline bool operator==(const ST_TABLE& x, const ST_TABLE& y) 
  { return x.num == y.num; }

template<typename Iterator>
class DateEquals {
  Iterator begin_, end_;
public:
  DateEquals(Iterator b, Iterator e) : begin_(b), end_(e) {}
  void operator()( const typename iterator_traits<Iterator>::value_type& x ) 
const 
    { cout << std::find(begin_, end_, x)->data << endl; }
};

template<typename Iterator>
inline DateEquals<Iterator> make(Iterator b, Iterator e) 
  { return DateEquals<Iterator>(b,e); }

int main() {
  ST_TABLE array[] = {
    {  0,   0 }, {  1,  10 }, {  2,  20 }, {  3,  30 },
    {  4,  40 }, {  5,  50 }, {  6,  60 }, {  7,  70 },
    {  8,  80 }, {  9,  90 }, { 10, 100 },
  };
  cout << "配列でも:\n";
  for_each(array, array+11, make(array, array+11) );

  vector<ST_TABLE> vec(array, array+11);
  cout << "vectorでも:\n";
  for_each(vec.begin(), vec.end(), make(vec.begin(), vec.end()) );

  list<ST_TABLE> lst(array, array+11);
  cout << "listでも:\n";
  for_each(lst.begin(), lst.end(), make(lst.begin(), lst.end()) );
}

とほほ 2008/03/02(日) 07:14:22
επιστημηさんいつもお世話になります。
返信が遅れましたごめんなさい。

こんなんでいいのかしら。
ちょっといぢった。
迄は大体理解できました
最初value_typeの意味が理解できませんでしたが
単語の意味そのものでvector型とかlist型とか変数の型のことだと解釈しました
iterator_traitsはイテレータの特性を取得する関数のようですね
こんなのも有ったんですねといいますか
有るのは知っていましたが使い方、使う場面が分かっていない人でした

流石に
悪ノリ ^^;
template<typename Iterator>
inline DateEquals<Iterator> make(Iterator b, Iterator e) 
  { return DateEquals<Iterator>(b,e); }
この部分が何処に作用するのか今一理解できていない人なので
もう少し時間が掛かりそうです(^^;

それから最初に私の掲示したコードの下記の部分を

  int num = 1;
  while( num != vec.size() ) {
    vector<ST_TABLE>::iterator pos
      = find_if( vec.begin(), vec.end(), DateEquals( num ) );
    cout << pos->data << endl;
    ++num;
  }

このように
  int num = 1;
  int nPos;
  while( num != vec.size() ) {
    vector<ST_TABLE>::iterator pos
      = find_if( vec.begin(), vec.end(), DateEquals( num ) );
   nPos = pos->data;
   ++num;
  }

posの値は表示せず単に値だけを取得したい場合for_each構文は値を返さないので
素直にwhile構文を用いるのが吉ですか?

επιστημη [HomePage] 2008/03/02(日) 09:32:27
> posの値は表示せず単に値だけを取得したい場合for_each構文は値を返さないので
> 素直にwhile構文を用いるのが吉ですか?

「あなた次第」ですね。whileが素直と判断されるならそれでいいかと。

# for_eachは構文ではなく関数です、念のため。

とほほ 2008/03/02(日) 09:41:21
επιστημηさんおはようございます
>whileが素直と判断されるならそれでいいかと。
Effective STLでは、while文より関数オブジェクトを推奨していて
本当はwhile文は使いたくないのですが・・・

επιστημη [HomePage] 2008/03/02(日) 09:50:44
理解できません。

誰かが「主食はごはんよりパンがお薦め」ってゆったらごはんを断つの?

> while文より関数オブジェクトを推奨していて

その理由を吟味したうえでの判断? ならば文句ありません。

iijima 2008/03/02(日) 11:53:28
> Effective STLでは、while文より関数オブジェクトを推奨していて
> 本当はwhile文は使いたくないのですが・・・

Effective STLは私も参考にしています。
効率、正確さ、保守性の点でアルゴリズム呼び出しの方が「通常は」優れている、とは言
っていますが、「常に」そうであると言っているわけではないでしょう。

whileが素直だと思われるならば、その方が保守性が良さそうです。
今回の例ならば、whileとSTLで効率が格段に違う処理だとも思えません。
さらに、チームで開発しているとき、STLに詳しくないメンバーがいた場合はその学習の
ために開発の効率が下がったり、かえってエラーを仕込みやすくなったりするというリス
クもあります。

いろんな参考書でSTLを勉強するのは良いことですが、使いどころについては自分で判断
するしかないと思いますよ。

とほほ 2008/03/02(日) 12:00:31
[[解決]]
επιστημηさんiijimaさん忌憚のないご意見ありがとうございました。

レナ 2008/03/03(月) 09:45:42
 ああ

古いスレッドには追加発言できません。