お世話になります。
日付が格納されたコンテナと金曜日の日付が格納されたコンテナがあり
日付が格納されたコンテナから金曜日の位置を求めて別のコンテナに入れたいのですが
エラーが出ます。エラーの内容は
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
あああ
> for_each( vfriday.begin(), vfriday.end(), df.SetDistanceFriDay
(vyymmdd,*it) );
> 何処が間違っているのでしょうか
とんでもなく間違ってますが ^^;
for_eachの第3引数に渡すのはファンクタ(関数オブジェクト)です。
このコードによってなにをしたいのかがわかんないので、
答えられるのはここまで。
std::for_eachの第3引数に引き渡せる関数の型に合っていないからでは?
単純に考えると第3引数に引き渡せる_Fn1 は _Fn1(*iter) の形で呼び出せる必要があると
思いますが、違うのかな?
επιστημηさんPAITOさんお世話になります
大間違いのようですね・・・・
しばし考えますお時間をください。
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
とほほです。
お世話になります今調べています。
for_eachの第三引数に渡す変数が二項有って(vyymmddと*it)混乱しています
この場合mem_funまたはmem_fun_refを使った方がいいのでしょうか。または
template<typename Container, typename T>
このような形式からでも、二項渡せるのでしょうか
ヒントを頂けないでしょうか。
>tetrapodさんご指摘ありがとうございます
>distance の使い方もまちがってるが
distanceの使い方も間違ってますねT_T
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;
}
バグの原因に気付きました
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;
}
要約するに
・ v1 の中に v2 の要素があるかチェックし、あれば v1 のインデックスがほしい
っつーことでよいでっしゃろか?
v2 の要素のうち v1 中に見つからないものがあったときにどうなったらよいのか
(提示例は異常動作するよ)
両者の要素はソート済みかとか
要素に重複があったらどうしたいのかとか
その辺の詳細が決まっていないとコードにならないよ
ソート済み集合2つの積集合がほしいだけなら intersection でいけるけど
set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(),
std::back_inserter(v3));
インデックスが必要なんだよね・・・
tetrapod さんお手数おかけします。
>・ v1 の中に v2 の要素があるかチェックし、あれば v1 のインデックスがほしい
>っつーことでよいでっしゃろか?
はいその通りです
>v2 の要素のうち v1 中に見つからないものがあったときにどうなったらよいのか
v2コンテナ(金曜日の日付)は元々v1コンテナ(ソート済みのある一定期間の日付)の要
素から抽出した要素なので、理論的にはありませんが万が一その様な事態に陥った場合例
外処理で逃げますのでその事は無視してくださって結構です。
>両者の要素はソート済みかとか
>要素に重複があったらどうしたいのかとか
v1、v2それぞれのコンテナの要素はソート済みで且つ重複はございません。
>インデックスが必要なんだよね・・・
そうなんですよ
transform()関数が使えそうな気がしたんですが調べるとtransform()関数は
自身のエレメントに作用させる関数のようなので使えない気がします
やっぱりfor_each()関数と関数オブジェクトの組み合わせが良い気がするのですが
今επιστημη さんの監修されたSTL標準講座で簡単な例をじっくり読んでいるところで
す。
↓使えそうなのがないなら作ればいいわ。
#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;
}
επιστημηさんお手数おかけします
そしてありがとうございますその後、見よう見まねで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);この部分に作用していると理解しましたが間違っていませんでしょうか。
くどいようですが
以上宜しくお願い致します。
> 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