std::for_each error C2784:について – プログラミング – Home

通知
すべてクリア

[解決済] std::for_each error C2784:について

固定ページ 1 / 2

とほほ
 とほほ
(@とほほ)
ゲスト
結合: 17年前
投稿: 23
Topic starter  

お世話になります。
日付が格納されたコンテナと金曜日の日付が格納されたコンテナがあり
日付が格納されたコンテナから金曜日の位置を求めて別のコンテナに入れたいのですが

エラーが出ます。エラーの内容は
error C2784: '_Fn1 std::for_each(_InIt,_InIt,_Fn1)' : テンプレート 引数
を '_Fn1' に対して 'void' から減少できませんでした
このような内容でMSDNを読みますと。
「'宣言' : テンプレート引数を '型' に対して '型' から減少できませんでした
コンパイラでは、指定された関数の引数からテンプレートの引数を判断できません。」
と書いてあります。引数にはvector型とint型を渡しているつもりなのですが何処が間違
っているのでしょうかご教示宜しくお願い致します。

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

using namespace std;

class DistanceFriDay
{
int nPos;
vector<int>vDf;
public:
DistanceFriDay() : nPos(0){}
template<typename T>
void SetDistanceFriDay( const vector<T>& rVct, const int& ymd ) {
nPos = distance( rVct.begin(), ymd );
vDf.push_back( nPos );
}
vector<int>& GetDistanceFriDay(){return vDf;};
};

int main()
{
vector<int> vyymmdd;
vector<int> vfriday;

// データセット
vyymmdd.push_back(20080101);
vyymmdd.push_back(20080102);
vyymmdd.push_back(20080103);
vyymmdd.push_back(20080104);
vyymmdd.push_back(20080105);
vyymmdd.push_back(20080106);
vyymmdd.push_back(20080107);
vyymmdd.push_back(20080108);
vyymmdd.push_back(20080109);
vyymmdd.push_back(20080110);
vyymmdd.push_back(20080111);

vfriday.push_back(20080104);
vfriday.push_back(20080111);

DistanceFriDay df;
vector<int>::iterator it = vfriday.begin();
for_each( vfriday.begin(), vfriday.end(),
df.SetDistanceFriDay(vyymmdd, *it) );
return 0;
}

//VS2005 Express/STL


引用未解決
トピックタグ
ニアピン
 ニアピン
(@ニアピン)
ゲスト
結合: 17年前
投稿: 1
 

あああ


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

> for_each( vfriday.begin(), vfriday.end(), df.SetDistanceFriDay
(vyymmdd,*it) );

> 何処が間違っているのでしょうか
とんでもなく間違ってますが ^^;
for_eachの第3引数に渡すのはファンクタ(関数オブジェクト)です。

このコードによってなにをしたいのかがわかんないので、
答えられるのはここまで。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

std::for_eachの第3引数に引き渡せる関数の型に合っていないからでは?
単純に考えると第3引数に引き渡せる_Fn1 は _Fn1(*iter) の形で呼び出せる必要があると
思いますが、違うのかな?


返信引用
とほほ
 とほほ
(@とほほ)
ゲスト
結合: 17年前
投稿: 23
Topic starter  

επιστημηさんPAITOさんお世話になります
大間違いのようですね・・・・
しばし考えますお時間をください。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

distance の使い方もまちがってるが (このため余計にわけわからん)

distance(b, e) は vector に対して使ったら e-b なだけだよ
b から e を指し示すことが出来ない (=違う vector) 場合には未定義

vector<int> v(8); に対して
vector<int>::distance_type d1(distance(v.begin(), v.end())); // 8

bidirectional/random iterator であれば逆方向にアクセスすることが認められて
vector<int>::distance_type d1(distance(v.end(), v.begin())); // -8


返信引用
とほほ
 とほほ
(@とほほ)
ゲスト
結合: 17年前
投稿: 23
Topic starter  

とほほです。

お世話になります今調べています。
for_eachの第三引数に渡す変数が二項有って(vyymmddと*it)混乱しています
この場合mem_funまたはmem_fun_refを使った方がいいのでしょうか。または
template<typename Container, typename T>
このような形式からでも、二項渡せるのでしょうか
ヒントを頂けないでしょうか。

>tetrapodさんご指摘ありがとうございます
>distance の使い方もまちがってるが
distanceの使い方も間違ってますねT_T


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

えーっと・・・やりたいのはこーいうことなのかな?
http://ml.tietew.jp/cppll/cppll/article/4350


返信引用
とほほ
 とほほ
(@とほほ)
ゲスト
結合: 17年前
投稿: 23
Topic starter  

tetrapod さんお世話になります。
>えーっと・・・やりたいのはこーいうことなのかな?
関数オブジェクトを使わない方法で書くと
やりたい事は下記のようなことなのですが(ようなと書いたのは下記のコードにバグがあ
るからです、ごめんなさい)

下記のコードを実行すると
rhs.push_back(20080104);
rhs.push_back(20080111);
rhsコンテナはこの通りなのですが
2回目のループを実行すると
イテレータiteの値が
20080104

20080111
になると思うのですが
20080104

20080105
になってしまいアクセスバイオレーションが発生しまいます
混沌としてきました・・・・

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

using namespace std;

int main() {
vector<int> lhs;
vector<int> rhs;
vector<int> vec;
// データセット
lhs.push_back(20080101);
lhs.push_back(20080102);
lhs.push_back(20080103);
lhs.push_back(20080104);
lhs.push_back(20080105);
lhs.push_back(20080106);
lhs.push_back(20080107);
lhs.push_back(20080108);
lhs.push_back(20080109);
lhs.push_back(20080110);
lhs.push_back(20080111);

rhs.push_back(20080104);
rhs.push_back(20080111);
vector<int>::iterator ite = rhs.begin();
size_t pos_;
while( ite < rhs.end() ) {
ite = find( lhs.begin(), lhs.end(), *ite );
pos_ = distance( lhs.begin(), ite );
vec.push_back( (int)pos_ );
++ite;
cout << pos_ << endl;
cout << *ite << endl;
}
return 0;
}


返信引用
とほほ
 とほほ
(@とほほ)
ゲスト
結合: 17年前
投稿: 23
Topic starter  

バグの原因に気付きました
find()関数実行後の値がイテレータiteに代入されるので値が変わってしまっているよう
です
みっともないですが下記の様にしたら期待する動作となりました。
やりたい事はこの動作を関数オブジェクトを使って行いたいという事です。

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

using namespace std;

int main() {
vector<int> lhs;
vector<int> rhs;
vector<int> vec;
// データセット
lhs.push_back(20080101);
lhs.push_back(20080102);
lhs.push_back(20080103);
lhs.push_back(20080104);
lhs.push_back(20080105);
lhs.push_back(20080106);
lhs.push_back(20080107);
lhs.push_back(20080108);
lhs.push_back(20080109);
lhs.push_back(20080110);
lhs.push_back(20080111);

rhs.push_back(20080104);
rhs.push_back(20080111);
vector<int>::iterator ite = rhs.begin();
vector<int>::iterator ITE = rhs.begin();
size_t pos_ = 0;
while( ite < rhs.end() ) {
ITE = find( lhs.begin(), lhs.end(), *ite );
pos_ = distance( lhs.begin(), ITE );
vec.push_back( (int)pos_ );
cout << pos_ << endl;
cout << *ite << endl;
++ITE;
++ite;
}
return 0;
}


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

要約するに
・ v1 の中に v2 の要素があるかチェックし、あれば v1 のインデックスがほしい
っつーことでよいでっしゃろか?

v2 の要素のうち v1 中に見つからないものがあったときにどうなったらよいのか
(提示例は異常動作するよ)
両者の要素はソート済みかとか
要素に重複があったらどうしたいのかとか

その辺の詳細が決まっていないとコードにならないよ

ソート済み集合2つの積集合がほしいだけなら intersection でいけるけど
set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(),
std::back_inserter(v3));
インデックスが必要なんだよね・・・


返信引用
とほほ
 とほほ
(@とほほ)
ゲスト
結合: 17年前
投稿: 23
Topic starter  

tetrapod さんお手数おかけします。

>・ v1 の中に v2 の要素があるかチェックし、あれば v1 のインデックスがほしい
>っつーことでよいでっしゃろか?
はいその通りです

>v2 の要素のうち v1 中に見つからないものがあったときにどうなったらよいのか
v2コンテナ(金曜日の日付)は元々v1コンテナ(ソート済みのある一定期間の日付)の要
素から抽出した要素なので、理論的にはありませんが万が一その様な事態に陥った場合例
外処理で逃げますのでその事は無視してくださって結構です。

>両者の要素はソート済みかとか
>要素に重複があったらどうしたいのかとか
v1、v2それぞれのコンテナの要素はソート済みで且つ重複はございません。

>インデックスが必要なんだよね・・・
そうなんですよ

transform()関数が使えそうな気がしたんですが調べるとtransform()関数は
自身のエレメントに作用させる関数のようなので使えない気がします
やっぱりfor_each()関数と関数オブジェクトの組み合わせが良い気がするのですが
今επιστημη さんの監修されたSTL標準講座で簡単な例をじっくり読んでいるところで
す。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

↓使えそうなのがないなら作ればいいわ。

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

using namespace std;

template<typename InIterator, typename OutIterator, typename Function>
OutIterator iter_transform(InIterator first, InIterator last, OutIterator out,
Function func) {
for ( ;first != last; ++first) *out++ = func(first);
return out;
}

template<typename Iterator>
struct index : unary_function<Iterator,int> {
Iterator begin_, end_;
index(Iterator b, Iterator e) : begin_(b), end_(e) {}
int operator()(Iterator iter) const {
return static_cast<int>(distance(begin_, find(begin_, end_, *iter)));
}
};

int main() {
vector<int> lhs;
vector<int> rhs;
vector<int> vec;
// データセット
lhs.push_back(20080101);
lhs.push_back(20080102);
lhs.push_back(20080103);
lhs.push_back(20080104);
lhs.push_back(20080105);
lhs.push_back(20080106);
lhs.push_back(20080107);
lhs.push_back(20080108);
lhs.push_back(20080109);
lhs.push_back(20080110);
lhs.push_back(20080111);

rhs.push_back(20080104);
rhs.push_back(20080111);

iter_transform(rhs.begin(), rhs.end(), back_inserter(vec),
index<vector<int>::iterator>(lhs.begin(),lhs.end()));
for ( int i = 0; i < vec.size(); ++i ) {
cout << vec[i] << endl << lhs[vec[i]] << endl;
}
return 0;
}


返信引用
とほほ
 とほほ
(@とほほ)
ゲスト
結合: 17年前
投稿: 23
Topic starter  

επιστημηさんお手数おかけします
そしてありがとうございますその後、見よう見まねでmem_fun()関数を使って
書こうとしましたが書ききれませんでしたorz
掲示していただいたコードで二、三確認の意味でご教授願いたいのですが
宜しくお願いします。

template<typename InIterator, typename OutIterator, typename Function>
OutIterator iter_transform(InIterator first, InIterator last, OutIterator out,
Function func) {
for ( ;first != last; ++first) *out++ = func(first);
return out;
}

・この関数はiter_transform()関数を定義しているのでしょうか

template<typename Iterator>
struct index : unary_function<Iterator,int> {
Iterator begin_, end_;
index(Iterator b, Iterator e) : begin_(b), end_(e) {}
int operator()(Iterator iter) const {
return static_cast<int>(distance(begin_, find(begin_, end_, *iter)));
}
};

この部分がiter_transform()関数の関数オブジェクト部分である
index<vector<int>::iterator>(lhs.begin(),lhs.end()))
(関数オブジェクトとはbool値を返却するものなので用語の使い方が間違っているかも知
れませんが)
・この部分の動作を定義していると解釈しましたが間違ってませんでしょうか?

以上の私の解釈が間違っていなければ聞くまでも有りませんが念のために
この()演算子のオーバーロード関数ですが
int operator()(Iterator iter) const {
return static_cast<int>(distance(begin_, find(begin_, end_, *iter)));

・func(first);この部分に作用していると理解しましたが間違っていませんでしょうか。
くどいようですが
以上宜しくお願い致します。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

> template<typename InIterator, typename OutIterator, typename Function>
> OutIterator iter_transform(InIterator first, InIterator last, OutIterator
out,
> ...
>・この関数はiter_transform()関数を定義しているのでしょうか

YES

> template<typename Iterator>
> struct index : unary_function<Iterator,int> {
> ...
>(関数オブジェクトとはbool値を返却するものなので

NO! bool値を返すのは Predicate(述語)で、関数オブジェクトのひとつ。

> この部分の動作を定義していると解釈しましたが間違ってませんでしょうか?

YES

> int operator()(Iterator iter) const {
> return static_cast<int>(distance(begin_, find(begin_, end_, *iter)));
> ・func(first);この部分に作用していると理解しましたが間違っていませんでしょう
か。

OK


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました