[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 1001- 2chのread.cgiへ]
Update time : 05/09 22:57 / Filesize : 262 KB / Number-of Response : 1002
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

【C++】template 統合スレ -- Part6



1 名前:デフォルトの名無しさん mailto:sage [04/11/25 21:11:32]
C++ のジェネリックプログラミングの話をしましょう。
以下のスレッドを統合するスレです。
STLスレッド
Part1 pc.2ch.net/tech/kako/1004/10042/1004287394.html
Part2 pc3.2ch.net/tech/kako/1026/10267/1026793823.html

【C++】Boost使い集まれ!
pc3.2ch.net/test/read.cgi/tech/1033830935/ (html化待ち?)

Generic Programming with C++ Template
pc.2ch.net/tech/kako/1008/10085/1008593126.html
【C++】template 統合スレ -- STL/Boost/Loki, etc.
pc2.2ch.net/tech/kako/1037/10377/1037795348.html
【C++】template 統合スレ -- Part2
pc2.2ch.net/test/read.cgi/tech/1047978546/ (html化待ち)
【C++】template 統合スレ -- Part3
pc5.2ch.net/test/read.cgi/tech/1066493064/ (html化待ち)
【C++】template 統合スレ -- Part4
pc5.2ch.net/test/read.cgi/tech/1083550483/ (html化待ち)
【C++】template 統合スレ -- Part5
pc5.2ch.net/test/read.cgi/tech/1091522597/
関連スレ、その他リンクは >>2-5 あたりに。


636 名前:デフォルトの名無しさん mailto:sage [2005/05/24(火) 00:13:26 ]
>>635
テンプレートの話題ですよ。尤も、スレタイも読めないなら
このレスも読めない可能性、大。

637 名前:デフォルトの名無しさん mailto:sage [2005/05/24(火) 03:37:35 ]
暇つぶしに作ってた、ヘボコンパイラは出来上がったから
今度は、マジックリストクラステンプレートでも作ってみようかな
作ったらほしい人いる?

638 名前:デフォルトの名無しさん mailto:sage [2005/05/24(火) 08:09:05 ]
>>637 興味はある

639 名前:デフォルトの名無しさん mailto:sage [2005/05/24(火) 09:47:05 ]
学術的な興味なら。
ソースより測定結果をみたい。listやvectorとの比較つきで。

640 名前:デフォルトの名無しさん mailto:sage [2005/05/24(火) 15:44:00 ]
というか作りかけてる・・・

641 名前:デフォルトの名無しさん mailto:sage [2005/05/24(火) 22:41:55 ]
できたら
>>639もぜひ。

642 名前:デフォルトの名無しさん mailto:sage [2005/05/24(火) 23:45:11 ]
>>640
637だけど、あなたに任せます

643 名前:デフォルトの名無しさん mailto:sage [2005/05/25(水) 01:39:21 ]
小規模だけど多次元配列のポインタがどうしても必要で、newも使いたくないから
std::vector<std::vector< ...> >
とかで書いてみたんだけど、4次元ぐらいからコンパイル時間が凄くかかる。
ま、コンパイル時に何がおきてるか想像すりゃ当たり前といえば当たり前だし、
コンパイル時だけの問題なので気にしなきゃいいんだけど、
環境になるべく依存しないで(boostとかは使えないし、VC,gcc両方通す必要あり)、
効率の良い方法がありまつかね。std::deque使ってもかわらなさそうだし。



644 名前:デフォルトの名無しさん mailto:sage [2005/05/25(水) 01:49:02 ]
>>643
その「多次元配列」のインターフェースを必要最小限に絞って、
pimpl なり抽象インターフェースなりでコンパイル単位を分ける。
基本だな。



645 名前:デフォルトの名無しさん mailto:sage [2005/05/25(水) 02:06:06 ]
>>644
dクス。
pimplイディオムは詳しくないので、Exceptional C++でも読んでみまつ。

646 名前:640 mailto:sage [2005/05/25(水) 02:46:33 ]
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/458.txt
面倒だったのでBoost使いました.1.32.0が必要です.すいません.
VC++7.1とGCC3.4.2(mingw)でコンパイル確認しています.
勢いだけで突っ走ったので激しく読みにくいコードで申し訳ないです.
イテレータが安定じゃないのでsplice系がイテレータ返さないと
使い物にならないので,イテレータ返すようにしてます.
std::listのインターフェースであと実装していないのはsortと演算子だけです.
でも今日はもう気力残ってません.パフォーマンス測定もしかりです.おやすみなさい.

647 名前:デフォルトの名無しさん mailto:sage [2005/05/25(水) 04:02:34 ]
void reverse() // throw()
{
head_ = decode(sentry_.code, head_);
}

感動してしまった。

648 名前:デフォルトの名無しさん mailto:sage [2005/05/26(木) 03:43:21 ]
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/468.txt
微妙なバカチョンと例外飛んだときのバグを直しました.多分これで完璧なつもりです.
ただ,相変わらずsortだけ面倒なので実装してないです.
指摘されていたこととは言え,このデータ構造イマイチ利点がぼやけてますね.
特にアラインメントの関係でノードのサイズが普通のリストのそれと
同じになってしまう(32-bitマシンでmagic_list<double>とか)場合もあったりで散々かも.
唯一,647さんが指摘されているように要素順の反転を定数時間でできるのが
大きな特色ですけれど,それがうれしい状況ってあるんでしょうか・・・.

649 名前:デフォルトの名無しさん [2005/06/06(月) 11:28:39 ]
質問です。
「具現化によって生成された実体」 = 「ユーザー定義ではないスペシャライゼーション」
という理解でいいの?

650 名前:デフォルトの名無しさん [2005/06/07(火) 22:08:43 ]
"template テンプレート パラメータ"の意味が理解できないッス。
"Modern C++ Design" P11 の以下のコードなんですけど、

template <template <class> class CreationPolicy>
class WidgetManager : public CreationPolicy<Widget>
{
...
}

ここで template <class> に対して私の頭の中で
シンタックスエラーが発生します

template<class T> // ノーマル
template<> // 特殊化
template<class T=int> // デフォルト引数
template<class T, int=10> // 特殊化とデフォルト引数

というシンタックスは理解できています。
template <class> って何者? 誰か教えてください。

651 名前:デフォルトの名無しさん mailto:sage [2005/06/07(火) 22:12:38 ]
省略されてるだけ。
template <class /*T*/>
class foo;

652 名前:デフォルトの名無しさん mailto:sage [2005/06/07(火) 22:27:41 ]
>>651
サンクスです。とすると何らかの型を受け取るけど、
その型の情報は無視するよ、っていうことなんですね。
これをもとにもう一回読んでみます。

653 名前:デフォルトの名無しさん mailto:sage [2005/06/07(火) 22:32:56 ]
>>650
int f(int i);
int g(int); // これも脳内エラーが出るか?

654 名前:デフォルトの名無しさん mailto:sage [2005/06/08(水) 00:28:08 ]
>>650

例えば、

template< template<class T, class A> class Vector>
struct hoge
{
typedef T value_t;
};

typedef hoge<std::vector> hv_t;

としても、この時点では”T"はまだ決まってないわけだから
名前付けても使えないのです。
無論、”Vector"もこのままでは使えません。

実際の使用には

template< tempalte<class,class> class V>
struct hoge
{
template<class T,class A>
struct bind
{
typedef V<T,A> type;
};
};

typedef hoge<std::vector> hv;
typedef typename hv::template bind<int,std::allo..>::type
のように使うことになりますね。




655 名前:デフォルトの名無しさん mailto:sage [2005/06/08(水) 00:31:15 ]
補足ですが、

使えない == typedefできないということです。


656 名前:デフォルトの名無しさん mailto:sage [2005/06/08(水) 00:41:11 ]
>>654-655 とても650の理解を助けるとは思えない。

657 名前:デフォルトの名無しさん mailto:sage [2005/06/08(水) 01:10:19 ]
間違ったことは言ってないが、質問の答えとしては完全にズレてるな。

658 名前:654 mailto:sage [2005/06/08(水) 01:22:29 ]
>>656-657

この場合
>"template テンプレート パラメータ"の意味が理解できないッス。
と書いてあるところから、名前云々は関係ないと思うのですが・・

659 名前:デフォルトの名無しさん mailto:sage [2005/06/08(水) 10:35:01 ]
>>658 会話になってないな。もういいから喋るな。

660 名前:デフォルトの名無しさん mailto:sage [2005/06/08(水) 21:38:27 ]
>>650です。
皆さんありがとうございます。
>>654さんのご意見もとても理解の助けになりました。

661 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 08:01:15 ]
typedf templateってどうなったの?

662 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 08:13:16 ]
template< template<class T, class A> class Vector>
struct hoge
{
typedef T value_t;
};
template<class B> typedef hoge<std::vector<B> > hv_t;
typeof(hv_t<int>::value_t) i;

みたいにtypedefの一文をテンプレート化できるんだっけ。

663 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 08:32:30 ]
>>662
それはだめだろ。
template-templateパラメタのtemplateパラメタ(この場合T)
に言及するのは意味的におかしい。

664 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 08:43:39 ]
こうじゃないか?

template <typename> struct hoge;
template <template <typename, typename> class V, typename T, typename A>
struct hoge<V<T, A> >
{
typedef T value_t;
};
template <typename T> typedef hoge<std::vector<T> > hv_t;
hv_t<int>::value_t i;



665 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 08:49:01 ]
typedef templateを導入するなら変数templateや名前空間templateも欲しい。

と無責任に言ってみるテスト。

666 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 08:56:13 ]
>>664
あーなるほど。C++よく分らないから適当に書いてみたんだけどそれなら理解できるw

>template <template <typename, typename> class V, typename T, typename A>
> struct hoge<V<T, A> >
こうやって部分的特殊化で各パラメータ間の関係を表現できるのね。

>>663
>template <typename T> typedef hoge<std::vector<T> > hv_t;

問題はこの部分で、パラメータvector<T>の高階性(?!)を維持してくれるのかどうかってところかねえ。

>>665
変数templateとはどんなもんでしょ?

667 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 11:34:08 ]
もしも変数テンプレートがあったとしたらこんな感じ?
template <typename T> const T *NULL = 0;

int *pi = NULL;
char *pc = NULL;

#include <cstdio>
int main() {
  std::printf("%p", NULL<void *>);
}

668 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 11:59:30 ]
>>667
>int *pi = NULL;
>char *pc = NULL;
これを許すとまた規則が複雑になるな。

669 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 12:14:33 ]
class null {
public: template<typename T> operator T*() const { return 0; }
};

const null NULL;

int *ip = NULL;
char *cp = NULL;

printf("%p", (void*)NULL);

でいいような気がす

670 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 12:16:52 ]
誰もそんな話ししてないわけだが

671 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 13:24:53 ]
>>667
引数とるコンストラクターはどうなるんだ。

672 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 13:52:48 ]
typedef template ムチャ欲しいな。

673 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 14:26:04 ]
>>667
今のC++の型の取り扱いにあわせると

template<typename T> const T *NULL = 0;

は,右辺がリテラルの0でこれは型がintだからポインタ型に変換できず,
Tをどの型でinstantiationすれば良いのか判断できずコンパイルエラーになる,
っていう扱いが妥当だと思いますよ.
もうちょい厳密に変数テンプレートを定義しようとすると,
結局,型推論のためのautoキーワードの拡張

auto a = b; // typename(b) a = b; の構文糖

と同じになると思います.Andrew Koenigあたりがこのautoキーワードの代わりに
>>667の構文を提案してたはず.

674 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 14:35:13 ]
>>673
>>667の代わりに、
template <typename T> struct wrap{static const T *null;};
template <typename T> const T *wrap<T>::null = 0;
と書けることを考えると、今の扱いなら、

・template <typename T> const T *NULL = 0;
の時点では何も起こらない。
・printf("%p" NULL<void *>);
の点でインスタンス化が引き起こされ、void *const *を0で初期設定しようとし、成功。

が妥当じゃないのか?



675 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 14:50:45 ]
>>670
そうでなくて、必要性が全く感じられないと言っている
まともな利用例ぐらい出さないと

676 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 14:56:07 ]
>>674
その使い方だと常に明示的にインスタンス化しないといけない
(NULLを利用するたびに型パラメータを与えないといけない)わけですよね?
それは利用範囲が著しく限られませんか?

677 名前:667 mailto:sage [2005/06/09(木) 15:03:10 ]
ところで俺は変数テンプレートは全く要らないと思うんだけどな。
俺も669と同じようなのを考えたことはあるけど。

678 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 15:10:28 ]
>>676
使い道がないのは同意。
ただ、仮に現在のテンプレートの延長で「変数テンプレート」なるものを定義するなら、
>>674で言ったようになるはずだと思った。
>>673のような機能を導入するなら別の名前・構文を考えるべきだと思う。

679 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 15:26:38 ]
型推論はされるとして、
NULLみたいに初期化子に使うとちょっと面白そうな…

クラス階層のあるところでPTHREAD_MUTEX_INITIALIZERみたいなやつ。

680 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 15:29:21 ]
>>678
確かに「変数テンプレート」という名前は非常にまずいですね.
ただ構文については既存のキーワード使うとするとこれぐらいしかないような気がします.

681 名前:デフォルトの名無しさん mailto:sage [2005/06/12(日) 15:01:48 ]
アドビのオープンソースってど?流行ると思う?
STL、boostを基に、ウィンドウをスクリプトから生成する画期的システム
仮想マシンを実現とか、内容は理解を超えていた (つД`)

いわゆるチョット修正のときに威力を発揮すると思う
SEはどんな些細なこともPGに要望しなけりゃならない
PGは思いつきの修正のために仕事が増えるばかり
だれか人柱になってください、やっぱアドビ待ちなのかな

682 名前:デフォルトの名無しさん mailto:sage [2005/06/12(日) 17:16:13 ]
>>681
AdamとEve( ttp://opensource.adobe.com/ )のことか?なかなか
普及は難しいんじゃないかなぁ…

683 名前:デフォルトの名無しさん mailto:sage [2005/06/13(月) 00:40:41 ]
質問です。
BCC 5.5上のテンプレートのバグはどのようなものが
あるのでしょうか。

・・・特に大きいタイプリストを渡すと、他の特殊化に指定
したクラスが別のクラスに化けるとか、そんなのないですか?

684 名前:デフォルトの名無しさん mailto:sage [2005/06/13(月) 10:45:49 ]
>>683
質問するときはやりたいこと、実際にやったことを書いた方が良い。



685 名前:デフォルトの名無しさん mailto:sage [2005/06/13(月) 14:20:43 ]
>>683
どういうバグかは知らんがboostが満足に使えない。

686 名前:683 mailto:sage [2005/06/13(月) 21:39:52 ]
自己解決しちゃいました。

経緯だけ説明しますと、Modern C++ Designのマルチメソッドを
自分の使いやすい形に改良して使っていたんです。で特殊化の
際タイプリストを
template<..,class Head,class Tail>struct
Dispatcher<...,Typelist<Head,Tail>,...>{
...省略
};
と展開していて、6ほどの長さのタイプリストをわたしたところエラー吐かれました。
(5つまでは普通にコンパイル&動作しました)

これを
template<..,class TList>struct
Dispatcher<...,TList,...>{
...省略
};
としHeadにアクセスするときTList::Head,Tailにアクセスするときは
TList::Tailとするようにしたら今度は何十の長さでもコンパイルできました。

前者のコンパイルの仕方にバグがあるんでしょうかね・・・

687 名前:デフォルトの名無しさん mailto:sage [2005/06/13(月) 23:51:10 ]
BCCなんか使うなよ

688 名前:デフォルトの名無しさん mailto:sage [2005/06/14(火) 17:45:57 ]
もしかして、クラステンプレートのメンバ仮想関数って勝手に実体化される?

689 名前:デフォルトの名無しさん mailto:sage [2005/06/14(火) 17:58:42 ]
>>688
どんなコードでそう思った?

690 名前:688 mailto:sage [2005/06/14(火) 18:10:23 ]
ものすごく単純化すると、
class base
{
public:
virtual void foo() = 0;
};
template <class> class derived : public base
{
public:
virtual void foo() { std::cout << "呼ばれた\n"; }
};
int main()
{
derived<int> d;
static_cast<base&>(d).foo();
}
こんな感じ。

691 名前:デフォルトの名無しさん mailto:sage [2005/06/14(火) 18:24:16 ]
>>690
それってderived<int>型の変数dを宣言したからderived<int>が実体化されているだけのように見えるが。

692 名前:688 mailto:sage [2005/06/14(火) 18:28:53 ]
derived<int> が実体化されるのと
derived<int>::foo が実体化されるのは別じゃないですか?
クラステンプレートのメンバって呼ばれるまで実体化されませんよね?

693 名前:デフォルトの名無しさん mailto:sage [2005/06/14(火) 18:31:57 ]
>>688
規格では詳しくは規定されていないっぽい。
実際は
・derived<int>のインスタンスが宣言された
・derived<int>*からbase*の変換が行われた
のいずれかをトリガとして、仮想関数をすべて実体化することになると思う。

694 名前:688 mailto:sage [2005/06/14(火) 18:40:33 ]
>>693
サンクス。未定義ってことですか。
一応、明示的に実体化しておいたほうがよさそうですね。



695 名前:デフォルトの名無しさん mailto:sage [2005/06/14(火) 18:47:45 ]
>一応、明示的に実体化しておいたほうがよさそうですね。
なんでそうなる?

ついでに、「未定義」と「未規定」は違う。

696 名前:688 mailto:sage [2005/06/14(火) 18:50:17 ]
ん?
規定はされていなくても、正常に動くことは保証されているってことですか?

697 名前:693 mailto:sage [2005/06/14(火) 18:57:55 ]
言い方が不正確だったな。
規格には、「メンバ関数は、その定義が必要とされるとき実体化される(意訳)」とある。
で、virtual関数については、いつ「定義が必要とされる」か正確に規定している部分が(俺の見た限りでは)なかった。
従って、virtual関数の正確な実体化のタイミングは規定されていないことになる。
それでも、「必要」になり次第実体化されることは保障される。

698 名前:688 mailto:sage [2005/06/14(火) 19:22:06 ]
あー、なるほど。
規定されていないのは実体化されるタイミングだということですね。
どうもありがとうございました。

699 名前:デフォルトの名無しさん mailto:sage [2005/06/26(日) 18:25:16 ]
int k = 0;
for (vector< set<int> >::iterator it = v.begin(); it != v.end(); ++it)
it->insert(k++);

を boost::lambda か何かを使って for_each でシンプルに書けませんか?
メンバー関数に bind する仕方がよく分からないんですが・・・

700 名前:デフォルトの名無しさん mailto:sage [2005/06/26(日) 19:33:36 ]
>>699
typedef std::set< int > set_type;
typedef std::vector< set_type > vector_type;
void f( vector_type& v )
{
 using namespace boost::lambda;
 int k = 0;
 std::for_each(v.begin(), v.end(), (protect(bind((std::pair<set_type::iterator,bool> (set_type::*)(int const&))(&set_type::insert), _1, var(k)++)))(*_1));
}

○ boost::lambda か何かを使って
○ for_each で
× シンプルに

701 名前:700 mailto:sage [2005/06/26(日) 19:49:39 ]
メンバ関数に限らず、オーバーロードが絡むと lambda は使いにくいな。

702 名前:デフォルトの名無しさん mailto:sage [2005/06/27(月) 06:52:07 ]
protect要るか?

>>701
C++は名前が重なった場合の簡潔な指名定方法がないしね。
lambdaに限らず面倒。
typeofがBoostに入るそうだから、そのうち頑張って改善されるといいな。


703 名前:700 mailto:sage [2005/06/27(月) 07:50:29 ]
>>702
こんな感じで変形していったが、途中のやつの
エラーメッセージがひどくて(数100行ぐらい出る)、
何がまずかったのかよくわかってない。
× ((*_1)->*insert)(var(k)++)
× bind(insert, *_1, var(k)++)
○ (protect(bind(insert, _1, var(k)++)))(*_1)

704 名前:702 mailto:sage [2005/06/27(月) 22:11:02 ]
>>703
その3つの最初から間違ってるよ。
for_eachなんだから_1にはイテレータではなく参照が入る。よって
_1をdereferenceする必要はない。

まあ同じなんだけど、俺ならオーバーロードが絡む場合は
メンバ関数の特定を追い出すかな。
void hoge(vector<set<int> >& v) {
    typedef set<int> set_type;
    pair<set_type::iterator,bool>(set_type::*insert)(const int&)
        = &set_type::insert;

    int k = 0;
    for_each(v.begin(), v.end(), bind(insert, _1, var(k)++));
}




705 名前:700 mailto:sage [2005/06/28(火) 00:20:42 ]
>>704
うわ、とんでもない勘違いをしていたよ。
ありがとう。

706 名前:デフォルトの名無しさん mailto:sage [2005/07/05(火) 14:15:55 ]
ttp://d.hatena.ne.jp/soleil/searchdiary?word=%2a%5b%c5%fd%b7%d7%5d
ここに書いてあった
struct Mean
ってどう使うの? 例がないと分からない
functorなのは分かったけど

707 名前:デフォルトの名無しさん mailto:sage [2005/07/05(火) 14:27:54 ]
int array[] = {1, 3, 5};
std::vector<double> v = ...;

int ma = Mean<int *>()(array, array + 3);
double mv = Mean<std::vector<double>::iterator>()(v.begin(), v.end());

こんな感じじゃないか?

708 名前:デフォルトの名無しさん mailto:sage [2005/07/05(火) 16:19:10 ]
for_eachにかけるものではないのね
でも便利そう thx


709 名前:デフォルトの名無しさん mailto:sage [2005/07/05(火) 16:25:40 ]
>>707
のとおりにやってみたけど
コンパイル通らなかったよ

710 名前:デフォルトの名無しさん mailto:sage [2005/07/05(火) 17:04:14 ]
>>706
> 算術平均を求める Mean を書き直すと以下のようになる
> (もちろん Sum も反復子を使うように変更してあることが前提)

ちゃんとSumもコード書いた?

んで、漏れなら、合計値(累積値)を求めるアルゴリズムaccumulateを使い
平均値は:

void f(vector<double>& m) {
double avg = accumulate(m.begin(), m.end(), 0.0) / m.size();
}

のようにして求めるな。分散・標準偏差、RMSあたりも似たような実装ができる。


711 名前:デフォルトの名無しさん mailto:sage [2005/07/06(水) 04:42:18 ]
>>710
わざわざ関数にするのか?
コードの大きさを抑えるのにはいいけど。

712 名前:デフォルトの名無しさん mailto:sage [2005/07/06(水) 07:22:20 ]
>>711
しない。入力が何で出力が何か明確にしたかったので、関数形式で書いただけ。
実際に関数にするなら、template、inline、引数にはconst、戻値の型を明記、あたりが必要です。

蛇足で糞コード晒す。
template <typename T>
struct square : public binary_function<T, T, T> {
T operator()(const T& lhs, const T& rhs) { return lhs + rhs*rhs; };
};

double ms = accumulate(m.begin(), m.end(), 0.0, square<double>()) / m.size();
double rms = sqrt(ms);
double stdev = sqrt(ms - avg*avg);


713 名前:デフォルトの名無しさん mailto:sage [2005/07/06(水) 08:07:25 ]
STLは連続した、同じような事の繰り返し処理には滅法強いな。

714 名前:デフォルトの名無しさん mailto:sage [2005/07/06(水) 20:49:48 ]
>>713
あなたの人生もSTLで簡単になりますよ。

void silly_life(life& your_life)
{
  struct
  {
    static int daily(day& d)
    {
      d.nebou();
      d.nichan();
      d.onanu();
      d.shigoto();
      d.nichan();
      d.onanu();
      d.neru();
      return 0;
    }
  };

  std::for_each(your_life.begin(), your_life.end(), daily);
}

久しぶりにtemplate見たよ。。。C#使いづれ〜。。。orz



715 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 00:00:05 ]
それがSTLクオリティ。

語呂悪いな。

716 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 07:31:19 ]
速度が重要になるコードを書かなければなのですが、
やはりSTL経由の連続処理は、速度的に不利なんでしょうか?

一応自分なりに、次レスに書いたような実験をしてみたのですが、
プロファイル結果はSTL版hoge()が平均301msに対し、
シンプルなリストhage()の方が平均12msと、圧倒的な差に…。

今更自前リストなんて使うのは、考えただけで頭が痛くて。
なにかテストに落ちがないか、
或いはSTL版速度向上のための抜け道が無いか、教えて頂けないでしょうか。

717 名前:714 行制限のため、見づらくてすいません mailto:sage [2005/07/07(木) 07:35:09 ]
#include <list>
struct simple_list{
int val;
simple_list* next;
};
template <typename T>
void hoge( T first, T last ){
int sum = 0;
while( first != last ) sum += *(first++);
};
void hage( simple_list* sl_first ){
int sum = 0;
while( sl_first ){ sum += sl_first->val; sl_first = sl_first->next;}
};
int main(){
std::list<int> listInt;
for( unsigned long i=0; i < 100000; ++i ) listInt.push_back(i);

simple_list* sl_first = new simple_list;
simple_list* sl = sl_first;
for( unsigned long c=0; c < 100000; ++c ){
sl->val = c;
sl->next = new simple_list;
sl = sl->next;
}
sl->next = NULL;

hoge( listInt.begin(), listInt.end() );
hage( sl_first );
while( sl_first ){ sl = sl_first->next;delete sl_first; sl_first = sl; }
return 0;
}

718 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 07:51:04 ]
>>716
プロファイルでは最適化は有効にしてる?
最適化しないと比較にならないし、最適化すると hoge(), hage() が
sum を返してないので、最適化で処理自体が消えてダメかもしれない。

hoge の sum += *(first++); を { sum += *first; ++first } にすると、少し違うかもしれない。

719 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 07:51:41 ]
>>716
最適化した?
うちじゃ
hoge(): 8.46567 ms
hage(): 7.92051 ms
くらいなんだけど
環境はg++ (3.3.5)


720 名前:716 mailto:sage [2005/07/07(木) 08:08:12 ]
我ながら非道い
sl->next = NULL;を削って
sl->next = new simple_list; を
sl->next = (c != 100000-1) ? new simple_list : NULL; とでも

>>718-719
最適化をすっかり忘れていました。
なぜだかsumを返すようにしてもhogeの方が消えてしまうのですが
もう少し試行錯誤してみます。

いずれにせよ力づけられました。ホッとしています。
レスありがとうございました。

721 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 08:20:05 ]
>>720
返すだけで戻り値を使ってないんじゃ、と消えるかもしれないな。
チェックもかねて、画面に値を出すようにすれば大丈夫じゃない?
(そこまでやっても、ただの定数に置き換えてしまうコンパイラとかあるかもしれない。)

最終的にはアセンブリを吐かせて確認するといい。

722 名前:716 mailto:sage [2005/07/07(木) 08:25:49 ]
最適化無しで719さんの方法で15%ほど速く
>>721
もしかしたらtemplateだったせいかも知れないです。インライン化されていたのかな。
templateを外したらhogeも出ました

hoge: 5.579 ms
hage: 5.313 ms
(vc++6)

朝からお騒がせしました、お二人(三人?)に再度感謝です

723 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 08:31:10 ]
その程度の処理だとlistは兎も角、vectorは普通の配列と全く同じ速度出るよ。
#つーか、gccでもVC++でもstlの有無で全く同じ(質の)コード吐くんだけどね。

724 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 18:13:33 ]
>>723
VCだと
vector>=配列
になるときもない?(誤差範囲内だけど)
GCCは
vector使うと少し遅くなる気がした。




725 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 18:23:22 ]
その辺は具体的なコードを提示して比較でもしない限りなんとも言えないなぁ。
そもそも最適化で消えないコードでって条件になっちゃうし。

726 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 18:30:29 ]
vectorのiteratorは大抵の処理系/STL実装で非デバッグ時には単なるポインタだろ。

727 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 18:34:16 ]
>>722
ちなみに std::list が double-linked list だということは知ってるよな

728 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 23:52:14 ]
doubleじゃないSTLのlistを提示しない限りそのレスは無意味

729 名前:デフォルトの名無しさん mailto:sage [2005/07/08(金) 00:55:24 ]
>>728
おれは>727じゃないけど、なんで?

730 名前:デフォルトの名無しさん mailto:sage [2005/07/08(金) 01:02:35 ]
そういえばslistは標準じゃないんだな。 STLPortにはあるけど。

731 名前:デフォルトの名無しさん mailto:sage [2005/07/08(金) 20:43:04 ]
次のようなコードがあるとします:
 struct base1 { base1(int x) {}; };
 struct base2 { base2(int x, int y) {}; };

 // IF<P,T,F>クラステンプレートは、Pが非0のときT、0のときFをIF::typeにtypedefする
 template <int N> struct derived : public IF<N,base1,base2>::type {};

このとき引数の数が異なるコンストラクタを持つ基底クラスをテンプレートで切り替え、
派生クラスのコンストラクタから、基底クラスのコンストラクタを呼び出したいのです:
 derived<1> d(0); // base1から継承し、コンストラクタは引数1
 derived<0> d(0, 1); // base2から継承し、コンストラクタは引数2

基底クラスのコンストラクタを呼び出すときには、派生クラスの初期化リストを使います。
ところが、派生クラスのコンストラクタ初期化リストでは、基底クラスのコンストラクタ
以外呼べませんから、次のように多重定義できません:
 // Nが非0だとすると
 derived(int x) : base1(x) {};
 derived(int x, int y) : base2(x, y) {}; // error! 基底クラスはbase1

このように基底クラスをテンプレートで替える場合に、うまく派生クラスのコンストラクタの
引数の数を調整するようなテクニックがあれば、ご教示いただけると幸いです。
また、異なるアプローチもあればコメントください。


732 名前:デフォルトの名無しさん mailto:sage [2005/07/08(金) 20:50:10 ]
俺にはderivedをNの値によって特殊化する方法しか思いつかない。

733 名前:デフォルトの名無しさん mailto:sage [2005/07/08(金) 22:22:17 ]
試しにこう書いてみたら g++ 3.4.4 cygming special では通ったんだが。

derived(int x) : IF<N,base1,base2>::type(x) {}
derived(int x, int y) : IF<N,base1,base2>::type(x,y) {}

734 名前:731 mailto:sage [2005/07/09(土) 02:41:09 ]
>>732-733
レスありがとうございました。
>733の方法で、パパ、うまくできそうです。
続きがんばります!



735 名前:デフォルトの名無しさん mailto:sage [2005/07/09(土) 08:17:21 ]
どうもネットの世界の「ご教示」とか「ご教授」って浮いた言葉だなぁ。

736 名前:デフォルトの名無しさん mailto:sage [2005/07/10(日) 00:59:18 ]
実は初めてこの構文を知ったんだけどさ

>ttp://www.comeaucomputing.com/techtalk/templates/#esprobs
>
>template <class T>
>T foo(T blah)
>{
>    xyz object;
>    T someInt;
>
>// (略)
>
>    someInt = object.mt<int>(99.99); // AA: ill-formed
>    someInt = object.template mt<int>(99.99); // BB: well-formed
>
>    return someInt;
>}

ってなってて AA は ill-formed になってるんだけど、 object はテンプレートパラメータに依存してないんだから
template をつけなくても問題ないと思うんだけど。実際 g++ 3.4.4 だと通るし、. の前をテンプレートパラメータに
依存するように書き換えるとエラーが出る。

規格参照箇所 14.2-4
> When the name of a member template specialization appears after . or -> in a postfix-expression, or after
> nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a
> template-parameter (14.6.2), the member template name must be prefixed by the keyword template.
> Otherwise the name is assumed to name a non-template.






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<262KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef