επιστημηさん。
お世話になります、関数オブジェクトの使い方が少し分かってきました。
今日も関数オブジェクトの使い方で別の問題を抱えていましたが
(コンテナの先頭から最後尾までポインタ(iterator)を移動しながら隣り合ったエレメ
ントを減算し別のコンテナに代入する、私はtransformと二項関数オブジェクトの合わせ
技で解決しましたがもし何方かそのような事ができるアルゴリズムをご存知でしたら教え
てくださいませ)
STL標準講座とEffective STLを読みながら
なんとか自分自身で実装でき凄く気持ちよかったです。がしかし
果たしてこういう使い方は正しいのだろうかと疑心暗鬼の部分もあったりします。
ありがとうございました。
> 隣り合ったエレメントを減算し別のコンテナに代入する
#include <iostream>
#include <numeric>
using namespace std;
int main() {
int input[] = { 0, 1, 4, 9, 16, 25 };
int output[6];
adjacent_difference(input, input+6, output);
for ( int i = 0; i < 6; ++i ) {
cout << output[i] << ' ';
}
}
επιστημηさん
あのぉー
ありがとうございます。
>隣り合ったエレメントを減算し別のコンテナに代入する
有ったんですね・・・・・合掌
先にも書きましたが理解しながら自分で書けた関数オブジェクトなのですが
ダメだしお願い致します。
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
template <class T> class transmogrify :
public binary_function<T, T, T>
{
int result;
public:
result_type operator() (first_argument_type lhs, second_argument_type
rhs)
{
result = rhs - lhs;
return result;
}
};
int main() {
vector<int> lhs, result;
lhs.push_back(0);
lhs.push_back(1);
lhs.push_back(4);
lhs.push_back(9);
lhs.push_back(16);
lhs.push_back(25);
result.reserve(result.size() + lhs.size());
vector<int>::iterator itb = lhs.begin();
vector<int>::iterator ite = lhs.end() - 1;
vector<int>::iterator ITB = lhs.begin() + 1;
transform(
itb,
ite,
ITB,
back_inserter(result),
transmogrify<int>()
);
vector<int>::iterator itr = result.begin();
for( size_t i = 0; i < result.size(); ++i ) {
std::cout << *itr << ;
++itr;
}
return 0;
}
すいません少し修正です
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
template <class T> class transmogrify :
public binary_function<T, T, T>
{
public:
result_type operator() (first_argument_type lhs, second_argument_type rhs)
{
return rhs - lhs;
}
};
int main() {
vector<int> lhs, result;
lhs.push_back(0);
lhs.push_back(1);
lhs.push_back(4);
lhs.push_back(9);
lhs.push_back(16);
lhs.push_back(25);
result.reserve(result.size() + lhs.size());
vector<int>::iterator itb = lhs.begin();
vector<int>::iterator ite = lhs.end() - 1;
vector<int>::iterator ITB = lhs.begin() + 1;
transform(
itb,
ite,
ITB,
back_inserter(result),
transmogrify<int>()
);
vector<int>::iterator itr = result.begin();
for( size_t i = 0; i < result.size(); ++i ) {
std::cout << *itr << ;
++itr;
}
return 0;
}
...いんじゃないでしょか。
↓ちょびっとだけいぢった。
#include <iostream>
#include <algorithm>
#include <functional>
#include <iterator>
#include <vector>
#include <list>
// typedef std::vector<int> container;
typedef std::list<int> container;
using namespace std;
template <typename T>
struct transmogrify : binary_function<T, T, T> {
result_type operator() (first_argument_type lhs, second_argument_type rhs)
const
{ return rhs - lhs; }
};
int main() {
container lhs, result;
lhs.push_back(0);
lhs.push_back(1);
lhs.push_back(4);
lhs.push_back(9);
lhs.push_back(16);
lhs.push_back(25);
container::iterator itb = lhs.begin();
// +n, -n は random_access_iterator 以外では使えないので...
container::iterator ite = lhs.end(); advance(ite,-1); // or --ite;
container::iterator ITB = lhs.begin(); advance(ITB, 1); // or ++ITB;
transform(
itb,
ite,
ITB,
back_inserter(result),
transmogrify<int>()
);
copy(result.begin(), result.end(), ostream_iterator<int>(cout, ));
return 0;
}
ダメだししていいんだね・・・
vector であれば iterator+1 演算が出来るが list に対してはできないので
advance を使うほうがより一般的だと思う。
# distance 使ってたくらいだし...
back_inserter を使うのなら reserve は不要
(vector なら高速化のためあってもよい list ならそもそも不要)
差をとるのに binary_function<T,T,T> で良いのか?
[符号無し]引く[符号無し] であっても結果は [符号あり] である。
# unsigned int - unsigned int の結果は signed int で表現できないが・・・
少なくとも使う側に選択肢を与えることが出来るようにここの型表記は
template<T, U=T> ... : binary_function<T,T,U> としておくべきだろう
# std::minus() は <T,T,T> なので、俺はこいつを使わない主義
GCC では result_type や first_argument_type を transmogrify 中で使えない
(VC++ では使えるようだ:どっちが言語の挙動として正しいかは未検証)
U operator() (T l, T r) { return r-l; }
としておけば GCC でもコンパイルできる
えぴ氏の紹介の adjacent_difference は、マニュアル引けば書いて有るけど
こいつが返す最初の要素は差になっていないので注意!
επιστημη さん、tetrapod さん
お世話になります。
洽覧深識なご見解ご教授いただき感謝します。