05/05/15 22:32:53
ん?これでできてるっぽいぞ。
template<> A::A( int b);
512:デフォルトの名無しさん
05/05/15 23:29:21
>>511
あれ?本当だね。という事は、template <>の構文がちゃんとメンバテンプレート
に適用されているみたいだね。俺の勘では、明示的特殊化になってなくて、単なる
オーバーロードのような気もするが・・・・
513:デフォルトの名無しさん
05/05/15 23:36:57
もう少し規格票をよく読んでみる・・・・・
>>508はそしたら違う事に関してなのかな。
514:デフォルトの名無しさん
05/05/15 23:41:09
>>511
しかし、そのコードは構文的に正しいとは言えないですよね。
謎だ。
515:デフォルトの名無しさん
05/05/15 23:41:17
特殊化とインスタンス化とを混同してない?
516:デフォルトの名無しさん
05/05/15 23:55:33
>508が示したように、コンストラクタテンプレートに対して
テンプレート引数を明示する方法は無い。
しかし、(メンバ)関数テンプレートの特殊化を宣言する再には、
テンプレート引数を明示しなくても、関数引数の型から
テンプレート引数の推測が働く。
>>514
明示的特殊化の構文は
template<> delcaration
だから、>511は構文的に正しいと言える。
517:デフォルトの名無しさん
05/05/15 23:58:48
構文的には確かに正しいのだけれど、もともとの506の要求は
明示的インスタンス化(≠明示的特殊化)なわけで・・・
518:デフォルトの名無しさん
05/05/16 00:02:05
勉強になった。
519:デフォルトの名無しさん
05/05/16 00:08:01
>>517
それがどうした?
明示的インスタンス化の構文は
template declaration
だ。あとは同じ。
520:デフォルトの名無しさん
05/05/16 00:12:53
>>519
すまんすまん。それでVC++7.1で通ったよ。
521:デフォルトの名無しさん
05/05/16 00:15:29
コンパイラに「これこれのテンプレートをT型でインスタンス化しますた」
とレポートするスイッチがあればいいのに
522:デフォルトの名無しさん
05/05/16 00:17:31
実体化の位置を決定するルールは結構複雑だからな。
523:デフォルトの名無しさん
05/05/16 00:59:29
おまえらの必死さに笑った。
C++の中途半端なtemplate機能でメンテ不能の駄作を量産してる様は、
まるでVBで汎用ライブラリを作る馬鹿とそっくりだな。
524:デフォルトの名無しさん
05/05/16 01:03:16
C++知らないのに、知ってる振りして
がんばって煽るアンタもそうとう必死だが
525:デフォルトの名無しさん
05/05/16 01:35:46
むしろC++で駄目なのは
テンプレートじゃなくてコンストラクタ
526:デフォルトの名無しさん
05/05/16 01:47:19
>>525
コンストラクタの何が不満だって?
527:デフォルトの名無しさん
05/05/16 02:48:50
純粋なOO言語と比べると
C++のOOは不完全
528:デフォルトの名無しさん
05/05/16 03:05:21
>>526
class A
{
int a;
public:
A( int a_ ) : a(a_){;}
};
class B : A
{
public:
B(){ int a = 略; A::A(a);}
B( int a ) : B(){;}
};
529:デフォルトの名無しさん
05/05/16 03:16:11
何がしたいのか理解に苦しむ。C++について理解しているとは思えないコードだ。
530:デフォルトの名無しさん
05/05/16 03:30:52
>>529
これが出来ないから嫌だなと。
>B(){ int a = 略; A::A(a);}
これはAに突っ込む引数aを
Bのコンストラクタ内で生成したい時。
C++ではAのコンストラクタは、Bの初期化リストにしか
置けないので複雑なロジックは難しい。
>B( int a ) : B(){;}
これは多重定義したコンストラクタから
デフォのコンストラクタを予呼びたい時。
デフォのコンストラクタに生成時にかならず呼ばれる
初期化コードを収める。
これが出来ないと全てのコンストラクタに
同じ初期化コードを書かなければならない。
531:デフォルトの名無しさん
05/05/16 04:43:03
>>530
最初の:AはBの基底クラス。最初にAが構築されなきゃBが構築できない。
2番目の:B() {Init();} B(int a) {Init();hogehoge(a);}
532:デフォルトの名無しさん
05/05/16 08:55:21
最初のは
static int hoge() {return 略}
B() : A(hoge()) {}
とかすれば。
533:デフォルトの名無しさん
05/05/16 09:05:50
>>530
そういうことか。
ではどうしたらいいと思う?
Dは両方いけるんだっけか?
534:デフォルトの名無しさん
05/05/16 09:06:24
>>531
> Aが構築されなきゃBが構築できない
関係ない。
> Init()
Init() の中に初期化リストが書けない。
535:デフォルトの名無しさん
05/05/16 09:07:23
>>532
hoge() の値を初期化リストで2度使いたくなったらやっぱり困るな。
「略」が軽くて副作用がなければ、2回呼び出すんだろうけど。
536:デフォルトの名無しさん
05/05/16 09:10:37
要は設計が悪いんだろ。
537:デフォルトの名無しさん
05/05/16 09:18:31
まあそうだな。C++の設計の悪さは今更いかんともしがたい部分がある。
538:デフォルトの名無しさん
05/05/16 11:19:33
>>530
> C++ではAのコンストラクタは、Bの初期化リストにしか
> 置けないので複雑なロジックは難しい。
コンストラクタの途中でexceptionが起きたことを考えると、
>>532のような方法で初期化リストを旨く使う方法に頭を悩ませるのが良い。
>>528のやり方ではコンストラクト失敗時のデストラクトの扱いがかなり難しくなる。
初期化リストで上手くできない場合は、
exception safeの事を考えるとコンストラクタ自体がかなり複雑になってしまう。
539:>>538
05/05/16 11:21:07
定義順じゃなくて、初期化リスト記述順だといいのになあと思ったことはある。
540:デフォルトの名無しさん
05/05/16 12:06:24
>>539
それだと、コンストラクタごとに初期化順が変わってしまう。
Ex.
class foo {
public:
foo() : a_(), b_() {}
foo(int a) : b_(a), a_(a) {}
...;
};
541:デフォルトの名無しさん
05/05/16 12:21:40
>>540
539はまさにそれを意図しているのだと思うが、何か不都合があるの?
542:デフォルトの名無しさん
05/05/16 12:53:52
>>541
初期化リストに載ってないメンバはどうすればいい? by コンパイラ
543:デフォルトの名無しさん
05/05/16 13:14:10
くるしゅうない。よきにはからえ。
544:デフォルトの名無しさん
05/05/16 13:17:59
構築した順番の逆順で解体することを保証しなきゃならんので
コンストラクタごとに初期化順が変わったら大変だ。
545:デフォルトの名無しさん
05/05/16 14:05:33
なるほど。それもそうだ。
546:デフォルトの名無しさん
05/05/16 15:32:47
つーか藻前らEffectiveC++くらい読んどけよ。
547:デフォルトの名無しさん
05/05/16 20:25:46
template< uint n > class X
{
public:
void f(...);
}
こういうクラスがあったとして、
nが1だった場合 → X::f( uint f0 );
nが2だった場合 → X::f( uint f0, uint f1 );
nが3だった場合 → X::f( uint f0, uint f1, uint f2 );
こういうふうにテンプレート引数によって
関数の引数の数が変わるようにしたいんですが可能ですか?
出来ないまでも、代替手段みたいなのはありますか?
548:デフォルトの名無しさん
05/05/16 20:53:37
あの~
templateって実はマクロ?
549:デフォルトの名無しさん
05/05/16 21:23:34
>>547
関数のデフォルト引数でなんとかしろ。同一のテンプレートパラメータの型を
持つクラスは2回以上は定義できん。
550:デフォルトの名無しさん
05/05/16 21:58:37
>>549
了解、こういうのも出来るといいですね。
551:デフォルトの名無しさん
05/05/16 22:15:27
いやだから、ディフォルト引き数で何が不満なんだ?
552:デフォルトの名無しさん
05/05/16 22:22:47
それぞれ特殊化で可能じゃない?もちろんそうするのが良いか悪いかは別。
553:デフォルトの名無しさん
05/05/16 22:26:17
>>551
例えばベクトルクラスがあります。
template< uint n >class vector;
これをインスタンス化したい場合、こういうふうに書きたいんです。
vector<2> v2 = vector<2>(5,1);
vector<3> v3 = vector<3>(5,1,6);
vector<4> v4 = vector<4>(5,1,6,3);
vector<5> v5 = vector<5>(5,1,6,3,9);
vector<100> v100 = vector<100>(5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9);
自然な欲求だと思います。
554:デフォルトの名無しさん
05/05/16 22:31:08
>>553
そういう時のためのstd::vectorではないかと思うのだが・・・・
555:デフォルトの名無しさん
05/05/16 22:34:16
static const uint initialValues[] = {5, 1, 6, 3, 9,};
std::vector<uint> v5 = std::vector<uint>(initailValues, initialValues + sizeof(initialValues) / sizeof(*initialValues));
556:デフォルトの名無しさん
05/05/16 22:34:58
その例なら
配列を初期化して、std::vectorにぶち込めばいいじゃん
どうしてもやりたいならBOOST_PPで特殊化
557:デフォルトの名無しさん
05/05/16 23:09:19
部分特殊化。以降略。なんか馬鹿みてえ。
#include <iostream>
#include <cstddef>
template <std::size_t N, typename T = int>
class vec {
T a[N];
public:
vec(T i) {
a[0] = i;
std::cout << a[0] << std::endl;
}
};
template <typename T>
class vec<2, T>
{
T a[2];
public:
vec(T i, T j) {
a[0] = i; a[1] = j;
std::cout << a[0] << ' ' << a[1] << std::endl;
}
};
int main()
{
vec<1> v1 = vec<1>(5);
vec<2> v2 = vec<2>(5,1);
}
558:デフォルトの名無しさん
05/05/16 23:21:18
特殊化はイヤというか面倒くさすぎるから、普通はこんなカンジだろうね
template<uint Dim> class vector {
double *const coord;
public:
vector(double x) : coord(new double[sizeof(char[Dim == 1]) * Dim])
{ coord[0] = x; }
vector(double x, double y) : coord(new double[sizeof(char[Dim == 2]) * Dim])
{ coord[0] = x; coord[1] = y; }
vector(double x, double y, double z) : coord(new double[sizeof(char[Dim == 3]) * Dim])
{ coord[0] = x; coord[1] = y; coord[2] = z; }
};
int main() {
vector<1> v(1);
vector<1> v1(1, 2); // error
vector<2> v2(1, 2);
vector<2> vv2(1); // error
vector<3> v3(1, 2, 3);
}
559:デフォルトの名無しさん
05/05/16 23:24:56
やはりコンストラクタのオーバーロードに落ち着くか。
560:デフォルトの名無しさん
05/05/16 23:25:18
>>
そうするまでもなく
普通に多重定義でいいと思うよ。
template <std::size_t N, typename T = int>
class vec {
T a[N];
public:
vec( T x, T y)
{
if( N > 0 )a[0] = x;
if( N > 1 )a[1] = y;
}
vec( T x, T y, T z)
{
if( N > 0 )a[0] = x;
if( N > 1 )a[1] = y;
if( N > 2 )a[2] = z;
}
};
561:デフォルトの名無しさん
05/05/16 23:27:04
ちなみに、 sizeof(char[Dim == 1]) ってのは、
Dim == 1 のときは、1 で、そうでなければ、コンパイルエラーね
562:デフォルトの名無しさん
05/05/16 23:59:25
どうも読みにくいので、直した
template<unsigned Dim> class vector {
double coord[Dim];
public:
vector(double x) {
sizeof(char[Dim == 1]); // Dim == 1 でなければエラー
coord[0] = x;
}
vector(double x, double y) {
sizeof(char[Dim == 2]); // Dim == 3 でなければエラー
coord[0] = x; coord[1] = y;
}
vector(double x, double y, double z) {
sizeof(char[Dim == 3]); // Dim == 3 でなければエラー
coord[0] = x; coord[1] = y; coord[2] = z;
}
};
int main() {
vector<1> v(1);
vector<1> v1(1, 2); // コンパイルエラー
vector<2> v2(1, 2);
vector<2> vv2(1); // コンパイルエラー
vector<3> v3(1, 2, 3);
}
563:デフォルトの名無しさん
05/05/17 02:55:12
おまえらの必死さに笑った。
C++の中途半端なtemplate機能でメンテ不能の駄作を量産してる様は、
まるでVBで汎用ライブラリを作る馬鹿とそっくりだな。
564:デフォルトの名無しさん
05/05/17 02:57:49
×メンテ不能
○俺に理解不能
565:デフォルトの名無しさん
05/05/17 07:37:28
あーあ、4,5,6って別々にするわけ?テンプレの意味ねー
566:デフォルトの名無しさん
05/05/17 07:41:46
テンプレートはマクロ
www.iba.k.u-tokyo.ac.jp/~yanai/template_tips.html
567:デフォルトの名無しさん
05/05/17 10:05:48
>>563
まあ同意。boostとか見てても思うが、言語使用の範囲内でどうにかしようとするから無理が出てくる。
パズルとしては興味深いが、無理やりやってるからどうしてもキモくなる。
新しいプリプロセッサ作ったほうがマシな気がする。
568:デフォルトの名無しさん
05/05/17 12:24:00
>>566
典型的なアホっぽいが。
exportはComeauでサポートされていることすら知らんようだし。
569:デフォルトの名無しさん
05/05/17 12:40:07
>>566
> まず最も重要な事実は、templateはマクロであるということである。
そもそも、始めの仮定についてキチンと論証してない時点でアウトだな。
570:デフォルトの名無しさん
05/05/17 13:16:28
templateはマクロだよ。
マクロと聞いてCやC++のプリプロセッサ(やVBAなどアプリケーション内のスクリ
プティング言語)しか思いつかない人に向けた文章ではなかろ。
571:デフォルトの名無しさん
05/05/17 14:01:12
>ここではオブジェクト指向に則ったよいtemplateの使い方を模索する。
この時点で道を誤っている気が。
572:デフォルトの名無しさん
05/05/17 14:29:53
templateの明示的インスタンス化なんて、少し考えれば
使い道などろくに無い機能だとわかるだろうに
しかも使う必要も無い機能だし
それにこだわってる時点で、ダメだなそのページ
573:デフォルトの名無しさん
05/05/17 18:56:42
ネタをまじめに叩くなよ
574:デフォルトの名無しさん
05/05/17 20:39:55
ねたじゃねーし
templateはコンパイルする前に展開されるからマクロなの
575:デフォルトの名無しさん
05/05/17 20:42:50
コンパイルする前に展開しちゃったら
タイプセーフは無理じゃないの?
576:デフォルトの名無しさん
05/05/17 20:47:38
いいよわからん奴は無理に使うな
577:デフォルトの名無しさん
05/05/17 21:03:14
マクロで使える構文を限定的にして型を認識させたのがテンプレート
578:デフォルトの名無しさん
05/05/17 21:12:28
みんな好き勝手に「マクロ」の意味を定義して使ってるから、話が噛み合わない
だけでしょ。
579:デフォルトの名無しさん
05/05/17 21:56:51
おっと、ここで578が正式にマクロの定義とやらを教えてくれるらしいぞ
580:デフォルトの名無しさん
05/05/17 22:03:42
なにこの意味不明な反応
581:デフォルトの名無しさん
05/05/17 22:21:02
付き合うだけ無駄でつ
582:デフォルトの名無しさん
05/05/18 07:21:54
普通のマクロでも引数の数を変えられるようなことはできないから
>>553
583:デフォルトの名無しさん
05/05/20 00:28:48
VC7.1で
std::list<int>使うとポインタの保存のためか
std::vector<int>の3倍近いメモリ使うんだが、
省メモリな実装のlistって無理なのかな?
584:デフォルトの名無しさん
05/05/20 00:55:57
>>583
SGI STLのstd::slistなら、一方向リストだけど、少しでも少ないかも。
585:デフォルトの名無しさん
05/05/20 01:45:41
リストすら作りを理解してないのかよ。
586:デフォルトの名無しさん
05/05/20 12:25:58
std::vectorのresizeコストが気になるようならstd:;dequeとか
587:デフォルトの名無しさん
05/05/21 00:07:18
つうか双方向リストは最低2つはポインタが必要なんだから当たり前の気がするんだが
588:583
05/05/21 00:47:56
サイズは可変で大きい、挿入削除が定数時間(->list)、省メモリ(->vector)
を同時に満たしたかったので...
とりあえず挿入削除の速いlistを選択したけど、以外とメモリ食うって分かった。
小規模のvectorをlistで繋ぐか584さんのslistつかうのがいい気がしてきた。
双方向リストだとポインタが64bit化したらさらに事態は悪化するのも気になるし...
589:デフォルトの名無しさん
05/05/21 00:53:20
だから小規模なvectorをつなぐぐらいならdeque使えってばよ
590:デフォルトの名無しさん
05/05/21 00:54:03
>>587
要素が int で、双方向のポインタがあるわけで
それぞれサイズが同じなら、int の 3倍ですね。
>>585 も指摘してますが、糞当たり前です。
591:デフォルトの名無しさん
05/05/21 00:54:46
>588
データ構造の勉強からやり直して来い。
592:デフォルトの名無しさん
05/05/21 00:55:27
s/int の/1要素あたり int の/
593:デフォルトの名無しさん
05/05/21 00:56:22
>>588
中身の小さいオブジェクトを入れると、相対的にlistはポインタなどの管理部分が
大きく見えてしまうからねえ。
ケースバイケースで使い分けるしかない。
それとstd::slistのiteratorは、forward iteratorなので、bidirectional iteratorのlist
に比べると実行効率の悪いメンバ関数がいくつか存在するから、その点もよく確かめてね。
594:583
05/05/21 01:04:49
dequeだと
中間への挿入、削除した場合に
参照と反復子が死滅。
595:デフォルトの名無しさん
05/05/21 01:05:46
>>588
テキストエディタみたいに、挿入が同一箇所に連続して発生するようなら
ギャップベクタを検討するといいかも
596:デフォルトの名無しさん
05/05/21 01:34:23
>>594
それが問題になるなら、もう list しかないんじゃないかなぁ。
「小規模のvectorをlistで繋ぐ」なんてのも、全然ダメだろ。
597:デフォルトの名無しさん
05/05/21 01:43:48
もはやtemplateの話題じゃなくて、「データ構造とアルゴリズム」の世界だな。
598:デフォルトの名無しさん
05/05/21 02:11:25
listとかvectorはあるのに、より優れた概念のS式がないのはおかしい
599:デフォルトの名無しさん
05/05/21 03:42:02
>>598
あなたね(汗
インタプリタじゃないんですから。
600:デフォルトの名無しさん
05/05/21 05:55:52
>>599
もっと詳しく。
・・・って言っても無駄か。
何もわかってないくせに噛み付いてるの見え見えだもんな。
601:デフォルトの名無しさん
05/05/21 08:25:20
S式ってツリー構造じゃ無かったっけ?違った?
602:デフォルトの名無しさん
05/05/21 08:41:31
>>600
赤黒木だけじゃ足りないってのかい。
603:デフォルトの名無しさん
05/05/21 09:18:31
>>597
STLネタがそっちに向かうのは自然だと思うけど?
604:デフォルトの名無しさん
05/05/21 09:22:59
> つうか双方向リストは最低2つはポインタが必要なんだから当たり前の気がするんだが
直前の要素のポインタと直後の要素のポインタの排他的論理和演算結果を保持しておけ。
そうしておけばポインタ1つで双方向からリストをたどることができる。
実行時にそれなりのコストはかかるが、、、
605:デフォルトの名無しさん
05/05/21 10:01:07
>>604
結局サイズは変わらないわけだが。
しかも「ポインタ同士のXOR」?ワケワカラン。
606:604
05/05/21 10:23:45
以下のようなリンクリストがあったとする。
A‐B‐C
この時、B のポインタ領域には &A ^ &C となる値がセットされることになる。
順方向でA、Bまで読み込んできた場合、Aのアドレスは判っているはず。
このため、&A ^ (&A ^ &C) を計算することでCのアドレスが取得できる。
同様に逆方向でC、Bまで読み込んでいる場合、Cのアドレスは判っているため、&C ^ (&A ^ &C) を計算することでAのアドレスが取得できる。
これが magic list というデータ構造。
607:デフォルトの名無しさん
05/05/21 10:35:12
>>606
代償としてイテレータのサイズが大きくなるから、使い道は微妙だけどな。
608:デフォルトの名無しさん
05/05/21 10:43:01
>>606
ふーん。
std::list の実装に使われてるのは見たこと無いんだけど、
標準コンテナの実装としては何か問題があるのかな?
と考えたら、イテレータを取得した後に要素の削除・追加をするとマズイような気がした。
609:デフォルトの名無しさん
05/05/21 10:44:00
>>604
リストを変更しないときのコストはたいしてかからないんじゃないか。
簡単なループの場合、movl (%eax),%eax が xorl (%eax),%eax になるだけだろう。
>>607
イテレータのサイズなんて問題になることがそうそうあるとは思えんが。
前後に追加削除があるとイテレータが無効になってしまうから
std::listとはコンパチにならなくなることの方がまだ問題になりそうだ。
610:604
05/05/21 10:50:55
>>607
イテレータのサイズとリンクリストに保持される各要素のデータサイズを同列で比較するのもどうかと思うが。
イテレータにポインタを2つほど追加したところで、8バイトしかサイズは増えない。
(処理が複雑化する分、イテレータオブジェクトのサイズはもう少し増えると思うが。)
しかし、双方向ポインタにしてしまうと、各要素毎に4バイトの投資が必要となる。
611:604
05/05/21 10:58:43
>>608>>609
確かにイテレータの取得後に前後の要素が追加削除されると痛い。
排他制御の問題を抱え込むから、std::list との互換性は考えない方が吉かと。
612:デフォルトの名無しさん
05/05/21 11:12:46
>>609
> 簡単なループの場合、movl (%eax),%eax が xorl (%eax),%eax になるだけだろう。
訂正。これ間違い。xor+mov*2(or xchg)になるな。
613:デフォルトの名無しさん
05/05/22 00:18:22
> サイズは可変で大きい、挿入削除が定数時間(->list)、省メモリ(->vector)
データの格納にset使うのってやっぱダメなのか?
setの中身はconst扱いだけど、外してswapして取り出して消して使ってるけど。
挿入時もヌルデータ入れて跡で要素をswapしてるんで無駄なコピーも出ない用に工夫して、、、
、、、、
vectorはサイズ増えると勝手に自分のコピー作るんで、reserveしなきゃならんので嫌だ。
lispは探索が遅いし。mapはそんなものに使うのもったいないし。
結論 : set使え!
614:デフォルトの名無しさん
05/05/22 00:31:16
setが泣いてるぞ
615:デフォルトの名無しさん
05/05/22 00:31:37
listのメモリ効率が気になるような状況でsetなんか使えるかよ
つーか、dequeって要素へのアクセスもそこそこ速くサイズ変更のコストも最小限なのになんで使われんのか。
616:デフォルトの名無しさん
05/05/22 03:41:02
>>615
dequeって要素へのアクセスもそこそこ速く
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
環境によってはlist並みに遅いわけですが何か?
OSやCPUは敢えて書かないが、STLportとかSTLportとかSTLportとか。
617:デフォルトの名無しさん
05/05/22 06:50:59
>>606
C++ でポインタにビット毎の論理演算なんて
吉外じみた真似、よく平気で出来ますね。
618:604
05/05/22 08:36:41
>>617
坊やだな、、、
ポインタと言えど所詮はビット列なのだよ。
619:デフォルトの名無しさん
05/05/22 08:39:59
>>618
reinterpret_castとか使わないといけないんだろ?
環境依存イクナイ(・A ・)!
620:デフォルトの名無しさん
05/05/22 08:55:43
>>606
面白いなぁ
621:604
05/05/22 08:55:52
>>619
reinterpret_castが即、環境依存につながるとは新鮮な考え方だな。
同じ環境内でキャストして、同じ環境内で元に戻すのであれば、環境依存も何もないだろうに(それを環境依存というのなら、コンパイラが吐くコードはすべて環境依存になるぞ)。
それとも、そういうことすら期待できない処理系が現存するというのか?
(そんなのが出てきた時点で reinterpret_cast は言語仕様から外されるだろうて。)
622:デフォルトの名無しさん
05/05/22 09:07:29
>>621
愉快な香具師だなお前。
C++の実装と進化の§14.3.3(P420)読んでみろ。
623:デフォルトの名無しさん
05/05/22 09:09:30
>>622
○C++の設計と進化
×C++の実装と進化
それから、規格票を優先しろ。
624:604
05/05/22 09:17:26
その本は持ってない。
引用の範囲内だろうから、出典を明記して引用してくれ。
内容を咀嚼して説明してくれてもよいぞ。
625:620
05/05/22 09:35:20
俺の面白いは純粋な意味であって、622と同じ意じゃないですよ
626:デフォルトの名無しさん
05/05/22 09:38:55
5.2.10 Reinterpret cast
4 A pointer can be explicitly converted to any integral type large enough to hold it.
The mapping function is implementation-defined [Note: it is intended to be unsurprising
to those who know the addressing structure of the underlying machine. ]
5 A value of integral type or enumeration type can be explicitly converted to a pointer.
A pointer converted to an integer of sufficient size (if any such exists on the implementation)
and back to the same pointer type will have its original value; mappings between
pointers and integers are otherwise implementation-defined.
要するに規格としてはポインタ型を整数型にreinterpret_castして
その値をそのままポインタ型に戻す操作以外は完全に実装依存
627:604
05/05/22 09:57:53
「5.2.10 Reinterpret cast」の真意は、整数型にキャストし、演算後の《変更された値》をポインタにキャストし戻したとしても、それはポインタとして無効であるということだけだと思うぞ。
一例を挙げると、配列の特定要素を指すポインタを整数型に変換した後、インスタンスオブジェクトのサイズ分だけ値を加算し、ポインタ型に戻したとしても、次の要素へのポインタにはならないぞ、、、という。
Magic listにおける A-B-C という例において、Bに保存されている値はAのアドレスとCのアドレスを特定のルールで「エンコード」しただけの整数値であり、デコードすることにより元々のポインタ値を復元することが可能なはず(てーか復元できなければ意味はない)。
このため、上記の§5.2.10の規則には抵触しないと思うが?
むしろ「A pointer *can be* explicitly converted to any integral type」と書かれている以上、そのことが保証されているとも取れる。
integral typeにして何の演算も許さず、元のポインタに戻すことしかできないのであれば、そもそもキャストする意味ないし。 まさかシリアライズするのか?、、、ってそれはあまりにも危険だしな。
628:デフォルトの名無しさん
05/05/22 10:18:14
>>626
ん?問題ないんじゃない?
同じポインタからは同じ整数になり、
同じ整数からは同じポインタになるっていう射影だよね。
この規格表のいいたいところは要するに、
アドレスが16違っている2つのポインタを、
整数に直した時も16違っているかどうかはわからないよ、
というだけの話じゃん。
629:626
05/05/22 10:20:55
>>627
>Magic listにおける A-B-C という例において、Bに保存されている値はAのアドレスとCのアドレスを特定のルールで「エンコード」しただけの整数値であり、デコードすることにより元々のポインタ値を復元することが可能なはず(てーか復元できなければ意味はない)。
>このため、上記の§5.2.10の規則には抵触しないと思うが?
>むしろ「A pointer *can be* explicitly converted to any integral type」と書かれている以上、そのことが保証されているとも取れる。
5.2.10/5はポインタを整数にreinterpret_castした後,その整数値を「そのまま何の演算も行わずに」
元のポインタ型に再度reinterpret_castした場合,元のポインタ値に復元されることを保証するものです.
604さんのmagic_listでは排他的論理和演算を取るため「そのまま」ではないものの
5.2.10/5は明らかにreinterpret_castによるpointer <-> integerの1対1写像を保証しているものと
読めるため確かにそのとおりですね.626は621に対する指摘のつもりでしたが,
いやはや指摘がまったく見当違いどころかむしろ621が正当である根拠になりえますね.
これまた大変失礼しました.
>>628
上に同じです.失礼しました.
630:デフォルトの名無しさん
05/05/22 12:18:47
magic list はネタとしては面白いが、現実には滅多に使われない
データ構造だな。この手のネタは Hakcer's Delight とか Knuth
センセの本を読むとイロイロ転がってるよ。
あと、現実のプログラミングだと、list に int 一個だけ入れるのも
珍しい気がする。手元のコードをいくつか見直してみたが、わりと
大きめの構造体を繋ぐか、スマートポインタを入れることが多い。
いずれにしてもポインタ二個分のメモリなんて誤差って感じ。
631:デフォルトの名無しさん
05/05/22 13:39:00
珍しいかどうかは、ともかく
メモリ云々行ってた奴は、たぶん初心者だから
初心者の戯言を、あまり真に受けないほうが
632:デフォルトの名無しさん
05/05/23 09:43:55
結論はvector使え、でいいのか?
633:デフォルトの名無しさん
05/05/23 09:54:29
>>632
いい
634:デフォルトの名無しさん
05/05/23 12:40:40
magic list は所詮オナニー
635:デフォルトの名無しさん
05/05/23 18:35:46
ここはジェネリックプログラミングの話題じゃないのか?
636:デフォルトの名無しさん
05/05/24 00:13:26
>>635
テンプレートの話題ですよ。尤も、スレタイも読めないなら
このレスも読めない可能性、大。
637:デフォルトの名無しさん
05/05/24 03:37:35
暇つぶしに作ってた、ヘボコンパイラは出来上がったから
今度は、マジックリストクラステンプレートでも作ってみようかな
作ったらほしい人いる?
638:デフォルトの名無しさん
05/05/24 08:09:05
>>637 興味はある
639:デフォルトの名無しさん
05/05/24 09:47:05
学術的な興味なら。
ソースより測定結果をみたい。listやvectorとの比較つきで。
640:デフォルトの名無しさん
05/05/24 15:44:00
というか作りかけてる・・・
641:デフォルトの名無しさん
05/05/24 22:41:55
できたら
>>639もぜひ。
642:デフォルトの名無しさん
05/05/24 23:45:11
>>640
637だけど、あなたに任せます
643:デフォルトの名無しさん
05/05/25 01:39:21
小規模だけど多次元配列のポインタがどうしても必要で、newも使いたくないから
std::vector<std::vector< ...> >
とかで書いてみたんだけど、4次元ぐらいからコンパイル時間が凄くかかる。
ま、コンパイル時に何がおきてるか想像すりゃ当たり前といえば当たり前だし、
コンパイル時だけの問題なので気にしなきゃいいんだけど、
環境になるべく依存しないで(boostとかは使えないし、VC,gcc両方通す必要あり)、
効率の良い方法がありまつかね。std::deque使ってもかわらなさそうだし。
644:デフォルトの名無しさん
05/05/25 01:49:02
>>643
その「多次元配列」のインターフェースを必要最小限に絞って、
pimpl なり抽象インターフェースなりでコンパイル単位を分ける。
基本だな。
645:デフォルトの名無しさん
05/05/25 02:06:06
>>644
㌧クス。
pimplイディオムは詳しくないので、Exceptional C++でも読んでみまつ。
646:640
05/05/25 02:46:33
URLリンク(kansai2channeler.hp.infoseek.co.jp)
面倒だったのでBoost使いました.1.32.0が必要です.すいません.
VC++7.1とGCC3.4.2(mingw)でコンパイル確認しています.
勢いだけで突っ走ったので激しく読みにくいコードで申し訳ないです.
イテレータが安定じゃないのでsplice系がイテレータ返さないと
使い物にならないので,イテレータ返すようにしてます.
std::listのインターフェースであと実装していないのはsortと演算子だけです.
でも今日はもう気力残ってません.パフォーマンス測定もしかりです.おやすみなさい.
647:デフォルトの名無しさん
05/05/25 04:02:34
void reverse() // throw()
{
head_ = decode(sentry_.code, head_);
}
感動してしまった。
648:デフォルトの名無しさん
05/05/26 03:43:21
URLリンク(kansai2channeler.hp.infoseek.co.jp)
微妙なバカチョンと例外飛んだときのバグを直しました.多分これで完璧なつもりです.
ただ,相変わらずsortだけ面倒なので実装してないです.
指摘されていたこととは言え,このデータ構造イマイチ利点がぼやけてますね.
特にアラインメントの関係でノードのサイズが普通のリストのそれと
同じになってしまう(32-bitマシンでmagic_list<double>とか)場合もあったりで散々かも.
唯一,647さんが指摘されているように要素順の反転を定数時間でできるのが
大きな特色ですけれど,それがうれしい状況ってあるんでしょうか・・・.
649:デフォルトの名無しさん
05/06/06 11:28:39
質問です。
「具現化によって生成された実体」 = 「ユーザー定義ではないスペシャライゼーション」
という理解でいいの?
650:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/06/07 22:12:38
省略されてるだけ。
template <class /*T*/>
class foo;
652:デフォルトの名無しさん
05/06/07 22:27:41
>>651
サンクスです。とすると何らかの型を受け取るけど、
その型の情報は無視するよ、っていうことなんですね。
これをもとにもう一回読んでみます。
653:デフォルトの名無しさん
05/06/07 22:32:56
>>650
int f(int i);
int g(int); // これも脳内エラーが出るか?
654:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/06/08 00:31:15
補足ですが、
使えない == typedefできないということです。
656:デフォルトの名無しさん
05/06/08 00:41:11
>>654-655 とても650の理解を助けるとは思えない。
657:デフォルトの名無しさん
05/06/08 01:10:19
間違ったことは言ってないが、質問の答えとしては完全にズレてるな。
658:654
05/06/08 01:22:29
>>656-657
この場合
>"template テンプレート パラメータ"の意味が理解できないッス。
と書いてあるところから、名前云々は関係ないと思うのですが・・
659:デフォルトの名無しさん
05/06/08 10:35:01
>>658 会話になってないな。もういいから喋るな。
660:デフォルトの名無しさん
05/06/08 21:38:27
>>650です。
皆さんありがとうございます。
>>654さんのご意見もとても理解の助けになりました。
661:デフォルトの名無しさん
05/06/09 08:01:15
typedf templateってどうなったの?
662:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/06/09 08:32:30
>>662
それはだめだろ。
template-templateパラメタのtemplateパラメタ(この場合T)
に言及するのは意味的におかしい。
664:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/06/09 08:49:01
typedef templateを導入するなら変数templateや名前空間templateも欲しい。
と無責任に言ってみるテスト。
666:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/06/09 11:59:30
>>667
>int *pi = NULL;
>char *pc = NULL;
これを許すとまた規則が複雑になるな。
669:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/06/09 12:16:52
誰もそんな話ししてないわけだが
671:デフォルトの名無しさん
05/06/09 13:24:53
>>667
引数とるコンストラクターはどうなるんだ。
672:デフォルトの名無しさん
05/06/09 13:52:48
typedef template ムチャ欲しいな。
673:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/06/09 14:50:45
>>670
そうでなくて、必要性が全く感じられないと言っている
まともな利用例ぐらい出さないと
676:デフォルトの名無しさん
05/06/09 14:56:07
>>674
その使い方だと常に明示的にインスタンス化しないといけない
(NULLを利用するたびに型パラメータを与えないといけない)わけですよね?
それは利用範囲が著しく限られませんか?
677:667
05/06/09 15:03:10
ところで俺は変数テンプレートは全く要らないと思うんだけどな。
俺も669と同じようなのを考えたことはあるけど。
678:デフォルトの名無しさん
05/06/09 15:10:28
>>676
使い道がないのは同意。
ただ、仮に現在のテンプレートの延長で「変数テンプレート」なるものを定義するなら、
>>674で言ったようになるはずだと思った。
>>673のような機能を導入するなら別の名前・構文を考えるべきだと思う。
679:デフォルトの名無しさん
05/06/09 15:26:38
型推論はされるとして、
NULLみたいに初期化子に使うとちょっと面白そうな…
クラス階層のあるところでPTHREAD_MUTEX_INITIALIZERみたいなやつ。
680:デフォルトの名無しさん
05/06/09 15:29:21
>>678
確かに「変数テンプレート」という名前は非常にまずいですね.
ただ構文については既存のキーワード使うとするとこれぐらいしかないような気がします.
681:デフォルトの名無しさん
05/06/12 15:01:48
アドビのオープンソースってど?流行ると思う?
STL、boostを基に、ウィンドウをスクリプトから生成する画期的システム
仮想マシンを実現とか、内容は理解を超えていた (つД`)
いわゆるチョット修正のときに威力を発揮すると思う
SEはどんな些細なこともPGに要望しなけりゃならない
PGは思いつきの修正のために仕事が増えるばかり
だれか人柱になってください、やっぱアドビ待ちなのかな
682:デフォルトの名無しさん
05/06/12 17:16:13
>>681
AdamとEve( URLリンク(opensource.adobe.com) )のことか?なかなか
普及は難しいんじゃないかなぁ…
683:デフォルトの名無しさん
05/06/13 00:40:41
質問です。
BCC 5.5上のテンプレートのバグはどのようなものが
あるのでしょうか。
・・・特に大きいタイプリストを渡すと、他の特殊化に指定
したクラスが別のクラスに化けるとか、そんなのないですか?
684:デフォルトの名無しさん
05/06/13 10:45:49
>>683
質問するときはやりたいこと、実際にやったことを書いた方が良い。
685:デフォルトの名無しさん
05/06/13 14:20:43
>>683
どういうバグかは知らんがboostが満足に使えない。
686:683
05/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:デフォルトの名無しさん
05/06/13 23:51:10
BCCなんか使うなよ
688:デフォルトの名無しさん
05/06/14 17:45:57
もしかして、クラステンプレートのメンバ仮想関数って勝手に実体化される?
689:デフォルトの名無しさん
05/06/14 17:58:42
>>688
どんなコードでそう思った?
690:688
05/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:デフォルトの名無しさん
05/06/14 18:24:16
>>690
それってderived<int>型の変数dを宣言したからderived<int>が実体化されているだけのように見えるが。
692:688
05/06/14 18:28:53
derived<int> が実体化されるのと
derived<int>::foo が実体化されるのは別じゃないですか?
クラステンプレートのメンバって呼ばれるまで実体化されませんよね?
693:デフォルトの名無しさん
05/06/14 18:31:57
>>688
規格では詳しくは規定されていないっぽい。
実際は
・derived<int>のインスタンスが宣言された
・derived<int>*からbase*の変換が行われた
のいずれかをトリガとして、仮想関数をすべて実体化することになると思う。
694:688
05/06/14 18:40:33
>>693
サンクス。未定義ってことですか。
一応、明示的に実体化しておいたほうがよさそうですね。
695:デフォルトの名無しさん
05/06/14 18:47:45
>一応、明示的に実体化しておいたほうがよさそうですね。
なんでそうなる?
ついでに、「未定義」と「未規定」は違う。
696:688
05/06/14 18:50:17
ん?
規定はされていなくても、正常に動くことは保証されているってことですか?
697:693
05/06/14 18:57:55
言い方が不正確だったな。
規格には、「メンバ関数は、その定義が必要とされるとき実体化される(意訳)」とある。
で、virtual関数については、いつ「定義が必要とされる」か正確に規定している部分が(俺の見た限りでは)なかった。
従って、virtual関数の正確な実体化のタイミングは規定されていないことになる。
それでも、「必要」になり次第実体化されることは保障される。
698:688
05/06/14 19:22:06
あー、なるほど。
規定されていないのは実体化されるタイミングだということですね。
どうもありがとうございました。
699:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/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
05/06/26 19:49:39
メンバ関数に限らず、オーバーロードが絡むと lambda は使いにくいな。
702:デフォルトの名無しさん
05/06/27 06:52:07
protect要るか?
>>701
C++は名前が重なった場合の簡潔な指名定方法がないしね。
lambdaに限らず面倒。
typeofがBoostに入るそうだから、そのうち頑張って改善されるといいな。
703:700
05/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
05/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
05/06/28 00:20:42
>>704
うわ、とんでもない勘違いをしていたよ。
ありがとう。
706:デフォルトの名無しさん
05/07/05 14:15:55
URLリンク(d.hatena.ne.jp)
ここに書いてあった
struct Mean
ってどう使うの? 例がないと分からない
functorなのは分かったけど
707:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/07/05 16:19:10
for_eachにかけるものではないのね
でも便利そう thx
709:デフォルトの名無しさん
05/07/05 16:25:40
>>707
のとおりにやってみたけど
コンパイル通らなかったよ
710:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/07/06 04:42:18
>>710
わざわざ関数にするのか?
コードの大きさを抑えるのにはいいけど。
712:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/07/06 08:07:25
STLは連続した、同じような事の繰り返し処理には滅法強いな。
714:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/07/07 00:00:05
それがSTLクオリティ。
語呂悪いな。
716:デフォルトの名無しさん
05/07/07 07:31:19
速度が重要になるコードを書かなければなのですが、
やはりSTL経由の連続処理は、速度的に不利なんでしょうか?
一応自分なりに、次レスに書いたような実験をしてみたのですが、
プロファイル結果はSTL版hoge()が平均301msに対し、
シンプルなリストhage()の方が平均12msと、圧倒的な差に…。
今更自前リストなんて使うのは、考えただけで頭が痛くて。
なにかテストに落ちがないか、
或いはSTL版速度向上のための抜け道が無いか、教えて頂けないでしょうか。
717:714 行制限のため、見づらくてすいません
05/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:デフォルトの名無しさん
05/07/07 07:51:04
>>716
プロファイルでは最適化は有効にしてる?
最適化しないと比較にならないし、最適化すると hoge(), hage() が
sum を返してないので、最適化で処理自体が消えてダメかもしれない。
hoge の sum += *(first++); を { sum += *first; ++first } にすると、少し違うかもしれない。
719:デフォルトの名無しさん
05/07/07 07:51:41
>>716
最適化した?
うちじゃ
hoge(): 8.46567 ms
hage(): 7.92051 ms
くらいなんだけど
環境はg++ (3.3.5)
720:716
05/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:デフォルトの名無しさん
05/07/07 08:20:05
>>720
返すだけで戻り値を使ってないんじゃ、と消えるかもしれないな。
チェックもかねて、画面に値を出すようにすれば大丈夫じゃない?
(そこまでやっても、ただの定数に置き換えてしまうコンパイラとかあるかもしれない。)
最終的にはアセンブリを吐かせて確認するといい。
722:716
05/07/07 08:25:49
最適化無しで719さんの方法で15%ほど速く
>>721
もしかしたらtemplateだったせいかも知れないです。インライン化されていたのかな。
templateを外したらhogeも出ました
hoge: 5.579 ms
hage: 5.313 ms
(vc++6)
朝からお騒がせしました、お二人(三人?)に再度感謝です
723:デフォルトの名無しさん
05/07/07 08:31:10
その程度の処理だとlistは兎も角、vectorは普通の配列と全く同じ速度出るよ。
#つーか、gccでもVC++でもstlの有無で全く同じ(質の)コード吐くんだけどね。
724:デフォルトの名無しさん
05/07/07 18:13:33
>>723
VCだと
vector>=配列
になるときもない?(誤差範囲内だけど)
GCCは
vector使うと少し遅くなる気がした。
725:デフォルトの名無しさん
05/07/07 18:23:22
その辺は具体的なコードを提示して比較でもしない限りなんとも言えないなぁ。
そもそも最適化で消えないコードでって条件になっちゃうし。
726:デフォルトの名無しさん
05/07/07 18:30:29
vectorのiteratorは大抵の処理系/STL実装で非デバッグ時には単なるポインタだろ。
727:デフォルトの名無しさん
05/07/07 18:34:16
>>722
ちなみに std::list が double-linked list だということは知ってるよな
728:デフォルトの名無しさん
05/07/07 23:52:14
doubleじゃないSTLのlistを提示しない限りそのレスは無意味
729:デフォルトの名無しさん
05/07/08 00:55:24
>>728
おれは>727じゃないけど、なんで?
730:デフォルトの名無しさん
05/07/08 01:02:35
そういえばslistは標準じゃないんだな。 STLPortにはあるけど。
731:デフォルトの名無しさん
05/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:デフォルトの名無しさん
05/07/08 20:50:10
俺にはderivedをNの値によって特殊化する方法しか思いつかない。
733:デフォルトの名無しさん
05/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
05/07/09 02:41:09
>>732-733
レスありがとうございました。
>733の方法で、パパ、うまくできそうです。
続きがんばります!
735:デフォルトの名無しさん
05/07/09 08:17:21
どうもネットの世界の「ご教示」とか「ご教授」って浮いた言葉だなぁ。
736:デフォルトの名無しさん
05/07/10 00:59:18
実は初めてこの構文を知ったんだけどさ
>URLリンク(www.comeaucomputing.com)
>
>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.
737:デフォルトの名無しさん
05/07/10 02:07:52
template <typename T>
class Hoge {
public:
typedef std::vector<T> Container;
typedef Container::iterator Iterator;
private:
Container v;
};
と書いて、Hoge<int> hoge; とか呼ぶと、implicitなtypenameだと警告を言われます。
iteratorを表現するにはどのように記述すべきなのでしょうか。
738:デフォルトの名無しさん
05/07/10 02:09:19
>>737 gcc version 3.2 20020927 (prerelease) です。
739:737
05/07/10 02:11:47
URLリンク(www.tietew.jp) によると、
typename Container::iterator Iterator;
と書くみたいですね。これって常識なのかしら。
740:デフォルトの名無しさん
05/07/10 02:27:11
>>739
その場合、typenameは必須。
741:デフォルトの名無しさん
05/07/10 02:36:16
常識
742:デフォルトの名無しさん
05/07/10 04:36:52
当然
743:デフォルトの名無しさん
05/07/11 10:24:40
>>739
特殊化があるC++では、Tが確定しないと型推論が困っちゃうんで、
typedef typename Container::iterator Iterator;
って感じで。
typename Container::iterator Iterator;
も可能。
Container<int> v;
なら何とかなるはずだけど、explicitにtypenameしましょうという仕様。
744:デフォルトの名無しさん
05/07/16 20:53:42
>型推論が困っちゃう
そうなのか?
Tが確定しないと、特殊化のあるC++ではstd::vector<T>::iteratorが
typedefされた型名か、メンバ(メンバ変数・関数)かが分からないから
コンパイラへのヒントとして型名であることを明示するのを義務付けてるんでは?
745:デフォルトの名無しさん
05/07/19 22:11:08
全然わかってないけど質問します。
テンプレートクラスの実装って全てヘッダーでやらないといけないんですか?
.cppの方でやるとリンカーエラーが出てリンクできないのですが!?
(全部ヘッダーにコピペしたら通った)
746:デフォルトの名無しさん
05/07/19 22:14:53
追加
だが、しかしそれをやると2重定義になる…
どうすればいいんじゃーーーー
747:デフォルトの名無しさん
05/07/19 22:20:05
>>745
テンプレートの定義をcppファイルに書きたければ、宣言と定義の両方にexportを付けるだけ。
しかしほとんどのコンパイラで使えない。(使えるコンパイラが全くないわけではない)
というわけで普通はヘッダにインラインで全て書く。
ごく稀に明示的実体化が使われることはあるが。
748:デフォルトの名無しさん
05/07/19 22:48:35
>>747
明示的実体化ってまさか、
template class c<bool>;
template class c<char>;
template class c<unsigned char>;
みたいに延々と cpp ファイルに書いていくわけ?
749:デフォルトの名無しさん
05/07/19 23:06:05
g++にはextern templateってのがあるね。
750:デフォルトの名無しさん
05/07/19 23:11:50
>748
そゆこと。
751:745
05/07/19 23:17:21
やってみた>>747
make -k all
g++ -Wall main.cpp Class.cpp -c
g++ -Wall main.o Class.o -o a.exe
main.o(.text+0x25):main.cpp: undefined reference to `Class<int>::Class[in-charge]()'
collect2: ld returned 1 exit status
make: *** [all] Error 1
ムリポ
>>749を含めて出直してくる。これはイマの私の頭ではいくら考えても答えが出ない。
本を読むかg++のマニュアルを漁るか…
752:デフォルトの名無しさん
05/07/19 23:44:58
>>751
g++のinclude/bits/istream.tccより
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
// NB: This syntax is a GNU extension.
#if _GLIBCPP_EXTERN_TEMPLATE
extern template class basic_istream<char>;
extern template istream& ws(istream&);
extern template istream& operator>>(istream&, char&);
extern template istream& operator>>(istream&, char*)
753:デフォルトの名無しさん
05/07/23 19:33:12
template <class T> class foo;
template <class T> class baa{
friend foo;
int n;
public:
baa() : n(777){}
};
template <class T> class foo : public baa<T>{
int hoge;
public:
void set_val( baa<T>& arg ){ hoge = arg.n; }
};
int main(){
baa<int> b;
foo<int> f;
f.set_val( b );
return 0;
}
インデントが全角スペースですいません
これだとarg.nにアクセス出来ないのですが、間違っている場所を教えて頂けないでしょうか
friend foo; が、やっぱり
template <class T> friend foo; なんでしょうか
754:デフォルトの名無しさん
05/07/23 19:45:24
>>753
g++ でコンパイルすると、
:4: error: ISO C++ forbids declaration of `foo' with no type
:4: error: `foo' is neither function nor member function; cannot be declared friend
まぁそれは置いとくとして、
friend class foo<T>;
で通ったよ。
755:753
05/07/23 19:59:42
>>754
やっぱりclass指定しますよね
書き込む前にチェックしたサイトで、指定が無かったので、自分が間違っていたのかと
そうか、再度template <class T>付けるのは馬鹿でした。
VC6なので、Tが同じじゃなかったらアウトだったかも・・・良かった。
本当に助かりました。コンパイルまでして頂いてすいません。ありがとうございました。
756:デフォルトの名無しさん
05/07/23 20:13:13
baaっての…なんかプログラムがアホっぽくなるな。
757:デフォルトの名無しさん
05/07/23 22:22:39
>>755
friend かどうかっていう問題なのか?
baa<T>::n が private か protected/public かどうかっていう問題では?
758:デフォルトの名無しさん
05/07/23 22:47:57
>>757
vtableを避けるための小細工なんです
眉をしかめる人が多いと思いますが、自分しか使わないのでお見逃しを
759:デフォルトの名無しさん
05/07/23 23:36:56
>>758
よくわからないな。>>753 のを
template <class T> class baa{
protected:
int n;
public:
baa() : n(777){}
};
とすると VC6 だと vtable に関して状況が変わるの?
760:デフォルトの名無しさん
05/07/23 23:51:14
753がprotectedを知らなかったというオチ?
761:デフォルトの名無しさん
05/07/24 00:21:24
>>759
失礼、深読みしすぎてました。
しかしすいません、そうなると>>757で頂いたレスの意図が分からないです。
protectedすると、引数で他のbaaを受け取ったとき、nにアクセス出来るのでしょうか。
762:760
05/07/24 00:40:00
753のコードでは、bar<T>::nがprotectedならfoo<T>::set_valの中でarg.nにアクセスできると思っていたがそうではなかったようだ。
スマソ
763:デフォルトの名無しさん
05/07/24 01:03:17
>>761
アクセスできると思ってた。けど間違ってたのなら失礼。
・基本 class から 派生 class を public 継承したとき、
・基本 class の protected member である n について、
・派生 class から this の n にアクセスできる。
・派生 class から this 以外の n にアクセスできない。
ということかな?も一回勉強しなおそ。
・ある class の private member である n について、
・その class から this の n にアクセスできる。
・その class から this 以外の n にアクセスできる。
というのは間違いないと思うんだけど。
あと自分の VC7 は、これに関して template class かそうでないかによって
コンパイル結果が違うのもよくわからない。
764:デフォルトの名無しさん
05/07/24 02:17:54
勉強しなおした。>>763は間違い多数につきスルーよろしく。失礼しますた。
765:デフォルトの名無しさん
05/07/28 18:38:46
Compile-time if
で型でなく値を返すにはどうすればいいのでしょうか?
int v= boost::mpl::if_c< (sizeof(T) <= sizeof(double)), 10, 20 >::Value
はだめでした
766:デフォルトの名無しさん
05/07/28 19:41:12
>>765
boost::mpl::int_
を使って、型にマップすればいい。
767:デフォルトの名無しさん
05/07/28 19:56:38
>>765
struct R0 {
enum {value = 10};
};
struct R1 {
enum {value = 20};
};
template <typename T>
int func ()
{
typedef typename boost::mpl::if_c <(sizeof (T) <= sizeof (double)), R0, R1>::type Result;
return Result::value;
}
768:デフォルトの名無しさん
05/07/29 10:42:43
template<CONTANER>
class CmyContaner
{
typedef CONTANER::iterator iterator_type;
};
としたらコンパイル通らなかったんですが、
CONTANER::iteratorはできないってことなのでしょうか?
769:デフォルトの名無しさん
05/07/29 11:35:24
>>768
-typedef CONTANER::iterator iterator_type;
+typedef typename CONTANER::iterator iterator_type;
770:デフォルトの名無しさん
05/07/29 15:37:41
そのままじゃ型名かメンバ変数かわからんからね。
> CONTANER
北斗の拳の主題歌を思い出すスペルミスだな。
771:デフォルトの名無しさん
05/07/29 16:46:27
>>768
ここもだね
-template<CONTANER>
+template<typename CONTANER>
772:デフォルトの名無しさん
05/07/30 08:40:48
template<Functor>
class MyMethod
{
public:
Functor f_
MyMethod(Functor f):f(f_)
{}
value()
{
f_(10);
}
};
class MyClass
{
public:
struct MyFunctor{
operator()(int a)
{
std::cout << a;
}myFunc;
//MyMethod<MyFunctor> myMethod(myFunc);//コンパイル通らない
MyMethod<MyFunctor> myMethod(MyFunctor);//なぜかコンパイル通る
value(){
myMethod.value();//左側がクラス 構造体 共用体でありません と怒られる
}
};
クラスの中でfunctorを定義したら動かなくなりました。
回避方法はないのでしょうか?
773:デフォルトの名無しさん
05/07/30 09:48:49
>>772
>クラスの中でfunctorを定義したら動かなくなりました。
クラスの外でfunctorを定義したらそれ動く?
774:デフォルトの名無しさん
05/07/30 13:47:17
>772
とりあえず } が 1 個足りない。
} myFunc; の前に 1 個ある、でいいのか?
>MyMethod<MyFunctor> myMethod(MyFunctor);
これだと MyFunctor 型の引数をとり、MyMethod<MyFunctor> 型を返すメンバ関数 myMethod を
宣言しているんじゃまいか?
>//MyMethod<MyFunctor> myMethod(myFunc);//コンパイル通らない
なんでメンバ変数を宣言してるのに初期化しようとしてるの?
MyMethod<MyFunctor> myMethod;
MyClass() : myMethod(myFunc) {}
じゃねーのか?あと↑だと myFunc との初期化順序が問題になる場合があるかも。
今回の場合、MyClass() : myMethod(MyFunctor()) でいいような気もするが。
775:772
05/07/30 14:59:26
すみません } が1つぬけてました。
template<Functor> class MyMethod
にclass の外で定義したfunctorを使うと
意図したとうりの動きをすることを確認しています。
776:デフォルトの名無しさん
05/07/30 15:06:57
>>775
>class の外で定義したfunctorを使うと
>意図したとうりの動きをすることを確認しています。
本当に?
コピペにかなりミスがあると思うよ
MyMethod::value()
MyClass::MyFunctor::operator()(int a)
の返値の型は?
もし本当に動くなら処理系を教えてね
777:776
05/07/30 15:09:07
たぶんこんなことしたいのかな
template <typename Functor>
struct MyMethod {
Functor f_;
MyMethod (Functor f): f_(f) {}
void value () {f_ (10);}
};
struct MyClass {
struct MyFunctor {
void operator () (int a) {
std::cout << a;
}
} myFunc;
MyMethod <MyFunctor> myMethod;
MyClass (): myFunc (), myMethod(myFunc) {}
void value() {myMethod.value();}
};
778:デフォルトの名無しさん
05/08/02 22:23:20
template<X>
class CHoge
{public:
CHoge( X= typeof(x) ) {}
};
なんてできないの?
自動で型判別してほしい。
自動判別した型を使ってCompile-time Ifもできるとさらにいいんだけど
779:デフォルトの名無しさん
05/08/02 23:18:35
>>778
>自動で型判別してほしい。
>自動判別した型を使ってCompile-time Ifもできるとさらにいいんだけど
これらはできるけど
例で何がしたいのかさっぱり分かりません
780:デフォルトの名無しさん
05/08/05 23:15:18
template< ArrayType >
function( ArrayType array)
{
Compile-time If (ArrayType はポインタの配列?)
{
int a= array[0]->value;
}else{
int a= array[0].value;
}
こんなことがしたい
781:デフォルトの名無しさん
05/08/05 23:30:47
type_traitsでいいんじゃないの?
782:デフォルトの名無しさん
05/08/06 00:52:15
個人的には値の配列とポインタの配列を静的多相に扱おうとする行為そのものに
異議を申し立てたい.
783:デフォルトの名無しさん
05/08/06 02:36:31
次のようなコードが、Visual C++では通るけどGCCでは通りません。
オブジェクトの名前と番号の型を保持する構造体を用意
template<class S,class I>
struct Types
{
typedef S String;
typedef I Integer;
};
この定義を受け取って型を定義するベースクラスを作成
template<class T>
struct Base
{
typedef typename T::String StringType;
typedef typename T::Integer IntegerType;
};
そして、これを利用するサブクラスを作成。
template<class T>
struct Derived : public Base<T>
{
StringType name; //!< ここでコンパイルエラー
IntegerType number; //!< 同様
};
typedef Types<std::string,int> StdTypes;
Derived<StdTypes> derived;
784:デフォルトの名無しさん
05/08/06 02:38:23
続き
以下のように書けばGCCでもコンパイルは通ります。
typename Derived::StringType name;
typename Derived::IntegerType number;
こんな面倒な書き方しかできないなら、
わざわざベースクラスにtypedefした意味がないんですが
何かいい方法ありませんか?
785:デフォルトの名無しさん
05/08/06 02:58:54
>>783-784
Base の定義中に typename が必要な理由を知っていれば、無理だと予想が付くだろうに。
786:デフォルトの名無しさん
05/08/06 07:54:33
>>783-784
俺だったら
Base::Stringと書けないか
Derivedの中にusing Base::String;と書けばStringが使えないか
の2つをまず試してみる。これでできるかどうかはもちろんしらんが。
787:デフォルトの名無しさん
05/08/06 09:04:33
Baseを使うなら、
typename Base<T>::StringType name;
typename Base<T>::IntegerType number;
こうなるから、これこそ、
> わざわざベースクラスにtypedefした意味がない
ので、>>784のやり方が良いだろう。
VC++もそのうち>>783は駄目になることでしょう。
788:デフォルトの名無しさん
05/08/06 09:32:41
>>784
それVC7.1のバグらしい。
面倒見が良すぎて、typenameを本来ならば書かなければならない
所を、曖昧さがない場合は無くても通してしまう。
VC7.1でもちゃんと typename は書くべき。
789:デフォルトの名無しさん
05/08/06 12:59:29
このスレの難読コードをみて
おれにとて
C++はなかたことになた
790:デフォルトの名無しさん
05/08/06 13:03:53
そんなだから、未だに君にとってこの程度が「難読コード」なんだよ。
791:デフォルトの名無しさん
05/08/06 13:07:40
俺もtemplateのコードは可読性が低いと思うよ
唯一の弱点だな
792:デフォルトの名無しさん
05/08/06 13:32:35
テンプレートとC++「本体」って明らかに別の言語だよな。
概念の異なる2つの言語が混在してるんだから、
可読性が低いのは当たり前。
793:デフォルトの名無しさん
05/08/06 15:19:32
>>792
じゃあどういう構文にすればいいよ?
794:デフォルトの名無しさん
05/08/06 19:15:56
構文の話なのかな。
795:デフォルトの名無しさん
05/08/06 19:21:27
>>784
template<class T>
struct Derived : public Base<T>
{
typedef Base <T> Base_;
typedef typename Base_::StringType StringType;
typedef typename Base_::IntegerType IntegerType;
StringType name;
IntegerType number;
};
796:デフォルトの名無しさん
05/08/06 20:27:48
>>795 意味無いじゃん。
797:神゜
05/08/06 20:49:53
そろそろ俺の出番か?
798:デフォルトの名無しさん
05/08/06 21:04:29
>>784
ベースクラスがテンプレート依存でなければ StringType,IntegerType
は見えるが、そうでない場合は 795 のように書く必要がある。
実はずっと前の GCC で VC7.1 みたくエラーにならない時期が
あったんだが、バージョン上げたらエラーになったんで仕様を
確認したことがあったのを思い出したよ。
799:デフォルトの名無しさん
05/08/06 23:17:54
>>798
2.95あたりは確かそうだったね
800:デフォルトの名無しさん
05/08/07 16:48:53
template<class A>
struct Foo
{
template<class B>
struct Bar
{
};
};
このBarだけを特殊化するのって、GCCでは
template<>template<>
struct Foo<int>::Bar<int>
って書かなきゃならないんだね。
VC++7.1では
template<>
struct Foo<int>::Bar<int>
で通るんだけど、これはバグなのかな?
801:デフォルトの名無しさん
05/08/07 16:55:26
>>800
どっちが規格に準じてるかによるね
802:デフォルトの名無しさん
05/08/07 17:00:26
>>800
14.7.3.17 より
"If the declaration of an explicit specialization for such a member appears in namespace scope, the member declaration shall be preceded by a template<> for each enclosing class template that is explicitly specialized."
template<> template<> ... と繰り返すのが正解っぽい。
803:デフォルトの名無しさん
05/08/07 17:10:09
>>800
gccを信じてそちらに合わせておけ。
804:デフォルトの名無しさん
05/08/07 17:27:08
>>800
gccのバージョンは何?
g++ 3.3.5
だとそれ両方とも通るんだけど
新しいのは通らないのかな?
805:デフォルトの名無しさん
05/08/07 18:19:07
template <class T>
typename enable_if<boost::is_integral<T>, void>::type
foo(T t) {}
で関数を定義したりできないのはわかるけど
これでclassのコンストラクターを定義したりしなかったりを決めると
コンストラクターに戻り値が定義されています
と怒られる。何か方法ないのでしょうか?
template <class T>
class A{
typename enable_if<boost::is_integral<T>, void>::type
A(T t) { }
}
806:デフォルトの名無しさん
05/08/07 18:44:57
>>805
SFINAEは戻り値の型でやる方法と(デフォルト)引数の型でやる方法の2通りできて,
コンストラクタの場合は戻り値の型を指定できないですから引数の型のほうでやります.
template<class T>
class T{
A(T t, typename enable_if<boost::is_integral<T> >::type * = 0){}
};
こんな感じで.逆に演算子関数の場合は余計なデフォルト引数を指定できないので
戻り値型で,という感じになると思います.
807:デフォルトの名無しさん
05/08/07 22:38:01
enable_ifが何をするもんなのか、未だにわかんねえ。
てか、何年英語の勉強してもboostのドキュメントさえ読めない俺ってすげえよ。
よっぽど英語の才能が無いんだな。
808:デフォルトの名無しさん
05/08/07 22:41:04
テメェは自己紹介がしたいだけだろ
分からねぇんだったらイチイチ出てくんな
809:デフォルトの名無しさん
05/08/07 22:50:40
>>807
SFINAEによるオーバーロードセットのコントロールを簡単に
行うためのユーティリティ。
英語分からなくてもC++分かるんならひたすらソース詠めば
何となく見えてくる、かもよ。
810:デフォルトの名無しさん
05/08/07 22:53:46
>>808
なにキレてんのキミ。
相手以上の駄レス書いてたら意味無いのに。
811:デフォルトの名無しさん
05/08/07 22:59:07
駄レスとかいってたら、ほとんどがそうだろw
812:デフォルトの名無しさん
05/08/07 23:00:10
ほとんどがそうならなおのこと
突然特定のレスにキレる理由が無いよ。
813:デフォルトの名無しさん
05/08/07 23:03:27
自己顕示欲丸出しの厨房がウザイだけだろ
まあ、どこにでもいるからいちいちキレるのもどうかと思うが
814:デフォルトの名無しさん
05/08/07 23:16:33
キレて説教するほうがよっぽど自己顕示欲激しいと思う。
世に言う自爆ですな。アホくさ。
815:デフォルトの名無しさん
05/08/07 23:17:52
URLリンク(www.boost.org)
ここの「1.2 Background」は、何が問題だって言ってるんですか?
816:デフォルトの名無しさん
05/08/07 23:20:01
説教がどう自己顕示欲につながるんだ??
817:デフォルトの名無しさん
05/08/07 23:22:14
>>814
ワロス
818:デフォルトの名無しさん
05/08/07 23:29:27
>>816
キレるたびにいちいちスレ違いの書き込みするような奴が
自己顕示欲薄いって言い張る気?
819:デフォルトの名無しさん
05/08/07 23:30:34
enable_ifがわからんってののどこが自己顕示欲に繋がるのかもわからんけどな
820:デフォルトの名無しさん
05/08/07 23:30:49
>>818
藻前もキレてるじゃん
あと煽り耐性なさ過ぎ
いい加減スルーしろよ
821:デフォルトの名無しさん
05/08/07 23:31:47
>>815
いや,そこの部分は別に何かが問題だなんて書いてないです.
単にSFINAEというのがどう機能するか(そしてなぜそのような機能が必要なのか)
を説明しているだけです.
822:デフォルトの名無しさん
05/08/07 23:32:15
816が煽りには見えないけどなあ。
普通にズレてるだけで。
823:デフォルトの名無しさん
05/08/07 23:32:55
>>815
あっと,「もしSFINAEがなければこういうことが問題だよね」というのは書いてますけれど.
824:デフォルトの名無しさん
05/08/07 23:35:03
>>822
分かったからもう出てくんな
825:デフォルトの名無しさん
05/08/07 23:40:11
本日の推奨NG
「。」「顕示」「煽り」「キレ」
すっきりして(・∀・)イイ!!
826:デフォルトの名無しさん
05/08/08 02:07:36
expressional template
VC.net2003だと、ちょっと複雑な式を書いただけで
コンパイル通らない。
そういうものなの?
gccなら通るのかな
827:デフォルトの名無しさん
05/08/08 02:12:44
>>826 その「ちょっと複雑な式」とやらを晒すとレスが付くかもしれない。
828:デフォルトの名無しさん
05/08/08 03:35:21
>>826
現存する如何なるコンパイラでも通らない程複雑(広義の)なコードに問題ありに100円。
829:デフォルトの名無しさん
05/08/08 04:40:19
ネストが17超えるとか?
830:デフォルトの名無しさん
05/08/08 15:16:31
いろんな要素が混じってるので必ずしもexpressional templateが
原因でないのかもしれないけど
boost::numeric::ublas::matrix & A(){return A_ }
boost::numeric::ublas::matrix & B(){return B_ }
B() = prod( A(), A())*3 + B() + ....
こんな感じかな.全部はさらせないのですまそ
831:デフォルトの名無しさん
05/08/09 01:41:27
>>830
エラー貼ったがいいよ
もし膨大なら
再現するコンパイル可能な最小のコードを貼って
832:831
05/08/09 01:45:25
>コンパイル可能な
おっとコンパイルは通らないのか
>あなたがコンパイル通らないことを理不尽に思う
に訂正
ようするにテストする側の身になってコードを
貼ってください
833:デフォルトの名無しさん
05/08/09 11:45:51
>>830
>こんな感じかな.全部はさらせないのですまそ
じゃあ、他の人にエラーの原因を調べてもらうのも諦める事ですな。
証拠不十分なまま、証言台に立つような物ですぞ。
834:デフォルトの名無しさん
05/08/20 08:39:28
だれもいない
835:デフォルトの名無しさん
05/08/20 20:28:20
ホントにだれもいないのかよ
836:デフォルトの名無しさん
05/08/20 20:39:26
いねーよ
837:デフォルトの名無しさん
05/08/20 20:40:28
質問やら話題があれば人は自然と集まってくる。
838:デフォルトの名無しさん
05/08/20 20:52:57
おまえら
”てんぷれーと”にだまされてないか?
”しーぷらぷらのてんぷれーと”って結局あれだよ。
中途半端。
そう中途半端。
LISPに比べたら。
全然読み易くならない。
いろんな括弧であふれてLISPの方がまだサルのように読みやすい。
まあここにタムロしてるおまえらの言い分は判ってるよ
こうだろ、静的カタカタ型が重要なんです!
LISPじゃすぴーどでないよプププ
とかな。
ばーか。
カタなんかより柔軟性なんだよこのご時世はよ
カタカタうるせーのなんのって、笑うわ。
C++考えた奴みたいにハゲろ
全員
839:デフォルトの名無しさん
05/08/20 20:59:39
確かに、「ネイティブコード吐く言語じゃないと速度が」
とか必死に言ってる奴に優秀なプログラマはいないな。
840:デフォルトの名無しさん
05/08/20 21:10:42
しーぷらぷらの処理系。
てんぷれーとバグだらけ。
笑うわ。
いったい何年てんぷれーとやってんだよ
おまえらがべんだーの修正待つあいだに
おれLISPで新しいマクロどっさり作る
生産性バカたけぇーわLISPはよ
LISPはカタないからすぴーどでないよプププて、
そりゃ頭がかてえ証拠だな。
そんな奴は引退したほーがいいんじゃねーかなあ
LISPにカタないなら組み込めよ、ハゲども
ぶーとすとらっぷとか考えろよ
わかるか?ぶーとすとらっぷって。
しーぷらぷらにはそんながいねんはないかもなあ。
最適化なんかやりやすいなーすいすいいけるぜ
こんすの海の中にいると不満なんてすぐ解消する
それがLISP。
まあ頭のかたいカタカタ野郎は
やっぱりC++考えた奴みたいにハゲろ
全員
841:デフォルトの名無しさん
05/08/20 21:16:51
>>839よりは優秀だけどね。
842:マイク ◆yrBrqfF1Ew
05/08/20 21:31:32
C++をしーぷらぷらなんて言うのは無能。
843:デフォルトの名無しさん
05/08/20 21:59:52
C++でLisp系の俺言語&処理系作るのが最近の俺の趣味なんだが、
なんかこいつの仲間と思われたくないな、恥ずかしくて。
844:デフォルトの名無しさん
05/08/20 22:59:08
>>842
シープラスプラス?
それともシーたすたす?
845:デフォルトの名無しさん
05/08/20 23:33:28
しーいんくりめんと
846:デフォルトの名無しさん
05/08/20 23:43:58
C++
後置ということは、まだ本当のC++にはであてないわけだ
847:デフォルトの名無しさん
05/08/20 23:45:24
C++には出会えている
++Cに出会えてないだけ
848:デフォルトの名無しさん
05/08/21 00:37:45
838は、C++のテンプレートが読みにくく、
コンパイラのバグのことも分かっていて、
C++作った人物についても詳しいようだな
849:デフォルトの名無しさん
05/08/21 00:48:03
Schemeの純粋指向にはあこがれるけど、Lispはどうでもいいや。
継続は面白いな。
>LISPはカタないからすぴーどでないよプププて、
型が無いと遅くなるつうのは初耳ですが、どこの情報?
850:デフォルトの名無しさん
05/08/21 01:06:13
>>849
VBのバリアント型みたくデータ側に型情報があるから
オブジェクトを参照するたびに動的な判定が毎回必要ってことだよ。
型判定に値の取り出しとか最低でもCの3倍以上のコストが掛かる。
Rubyが遅いのもこれがかなり影響してる。
851:デフォルトの名無しさん
05/08/21 01:09:17
でも日本語は不自由なようだ。
852:851
05/08/21 01:09:45
>>838
853:デフォルトの名無しさん
05/08/21 01:25:23
> オブジェクトを参照するたびに動的な判定が毎回必要ってことだよ。
随分ダサい実装ですね。
854:デフォルトの名無しさん
05/08/21 01:41:07
そのダサイ実装を越えたところに桃源郷が
855:デフォルトの名無しさん
05/08/21 01:41:43
ももげんごう?
856:デフォルトの名無しさん
05/08/21 12:12:15
ももげんごう(←なか変換できない)
857:デフォルトの名無しさん
05/08/21 14:42:55
桃源郷=Xanadu キサナドゥ
858:デフォルトの名無しさん
05/08/22 00:38:44
>>850
正直、有名なコンパイラならそんなださい実装は少ないよ。
Common Lispには型指定の構文があるくらいだし。
859:デフォルトの名無しさん
05/08/23 09:18:30
数値計算したい人は
速度気にしないならlistでなくてMatlab使う
860:デフォルトの名無しさん
05/08/23 15:06:35
>>858
CLOS基地外氏ね
スレ違いだし
861:デフォルトの名無しさん
05/08/23 15:34:43
だれもいないからとか言うから
862:デフォルトの名無しさん
05/08/23 16:29:46
人稲杉なので、チラシの裏
boost::bind は、bind( f, _1, _2, a, b, _1 ) を行うことで、
func::return_type ( A1 & a1, A2 & a2 ) というファンクタを返すけど、
この _1 や _2 を、_decimal や、_text、_float のような書式指定プレイスホルダに
置き換えて、以下のようにすれば、タイプセーフな printf が出来るなと
考えたことがあった。
function< void( int ) > f = format( cout, "a = ", _hex, endl );
// ↑ cout << "a=" << %x << endl; と同じ事を行うファンクタを返す。
f( 10 ); // cout << "a=" << hex << 10 << endl;
f("aaa"); // コンパイルエラー
上の形とは違うけどその思想に基づいて実際に作ってみたことがある。
でも結局実用では (w)sprintf しか使わなかった。勉強にはなったけどね。
template プログラミングは楽しいけど、冷静なるとしなくていいことまで
テンプレート化してたりしていることがあるので気をつけないと。
863:デフォルトの名無しさん
05/08/23 17:12:40
>>862
> 冷静なるとしなくていいことまでテンプレート化してたりしていることがある
昨夜、そんな関数テンプレートを必死で非テンプレート関数に直してた・・・。
数日前に必死で関数テンプレートにした箇所だったのだけど・・・。
864:デフォルトの名無しさん
05/08/24 12:24:27
template<typename X_TYPE>
void xxx(X_TYPE x)
{}
として型の自動認識の手間減らしは多用するな
865:デフォルトの名無しさん
05/08/24 13:32:40
そうね。時々やる。いっそのこと型を書くのはオプションにして
MLみたいに型推論してくれればいいのにと思う。
866:デフォルトの名無しさん
05/08/24 17:50:00
C++ 0xだとそんな機能が追加されるとかされないとか。
867:デフォルトの名無しさん
05/08/28 09:36:27
テンプレートがちんぷんかんぷんでまったく理解できない私に
理解できるようになる方法を教えてください。まじで。
868:デフォルトの名無しさん
05/08/28 11:02:49
引数の型を使うときに決められるんだよ。
869:デフォルトの名無しさん
05/08/28 11:35:27
>>867
騙されたと思ってstd::min()でも使って味噌。
870:デフォルトの名無しさん
05/08/28 13:22:51
せめてstd::vector くらい使わないとありがたみ沸かないだろう。
871:デフォルトの名無しさん
05/08/28 18:04:02
>>867
つ[C++ Templates(英文)]
872:デフォルトの名無しさん
05/08/29 06:58:30
STL バンザイ
873:デフォルトの名無しさん
05/08/29 21:56:02
STLとboostが無かったら俺C++使いつづけて無かったよ。
874:デフォルトの名無しさん
05/08/29 22:30:29
俺もそうだ。
875:デフォルトの名無しさん
05/09/03 00:21:09
会社でtemplate使うなって言われたんだけど…
何故?
876:デフォルトの名無しさん
05/09/03 00:24:13
会社で使いこなせるヤシがいないからと邪推
877:デフォルトの名無しさん
05/09/03 00:31:06
代わりにLISP使え
もっと困るかもな
へへ
878:デフォルトの名無しさん
05/09/03 03:19:35
>>875
それは、あなたが馬鹿だからです。
879:デフォルトの名無しさん
05/09/03 03:26:37
お前だけは使うなって言われたなら
そうかもしれないけどさ
880:デフォルトの名無しさん
05/09/03 09:13:41
>>875
まともな会社にうつるべし
881:デフォルトの名無しさん
05/09/03 09:55:32
>>875
会社に聞け。
ここで聞くようなやつは>>878に決定。
882:デフォルトの名無しさん
05/09/03 10:02:04
>>881
なんでそんな必死にこの話題にフタしたがるの?
コンプレックスでも刺激された?w
883:デフォルトの名無しさん
05/09/03 11:09:31
>>882
頭、大丈夫か?
884:デフォルトの名無しさん
05/09/03 14:45:37
VC6のプログラム保守してるとかじゃないのか>875
885:デフォルトの名無しさん
05/09/03 22:33:39
>>883
大丈夫だよ。
質問に答えられない誰かさんの頭は大丈夫じゃないみたいだけど。
886:デフォルトの名無しさん
05/09/04 03:17:12
・移植性重視
・扱える開発者が少ない or メンテする人が固定とは限らない
のどっちかだろうねえ
後者の事情のほうが多いと思うけども
887:デフォルトの名無しさん
05/09/09 02:16:23
管理職の団塊世代が、ピュアなC以外理解できないとか
888:デフォルトの名無しさん
05/09/09 22:28:28
名前空間→記述が冗長すぎる
テンプレート→制限が多すぎる
クラス→継承が可読性を悪化させる
その他→コンパイル時間が長すぎる
889:デフォルトの名無しさん
05/09/09 23:39:18
C++→俺が解からない
890:デフォルトの名無しさん
05/09/09 23:45:15
俺が解からない→みんなも解からない
891:デフォルトの名無しさん
05/09/10 02:04:02
>>886
>移植性重視
templateって移植性下がるの?
892:デフォルトの名無しさん
05/09/10 02:33:11
例えばGCCと心中するつもりならGCCで動けばOKって人もいるでしょ
893:デフォルトの名無しさん
05/09/10 02:46:27
>>891
ある程度ISO C++に準拠したコンパイラがない環境には移植できなったりだとか。
894:デフォルトの名無しさん
05/09/10 03:16:30
少なくとも、vc7.1とgccの両方で動くテンプレートくらい書けないと
話にならないと思うけど。
895:デフォルトの名無しさん
05/09/10 12:53:08
VC7.1とgcc3.3以降で動くテンプレート書くのは簡単だろ、どっちもほぼ100%標準準拠なんだから。
むしろVC6とかgcc3.2とかで動くか動かないか判断する方が難しいと思われ。
896:デフォルトの名無しさん
05/09/10 13:14:28
>>895
VC6とgcc3.2以前はもうあきらめた。
というかエラーメッセージすらとんちんかんな時があるのが頭痛い。
昔の仕事のプロジェクトコードのメンテでちょっとしたテンプレート書いてとかで
引っかかると泣きたくなる。