トップページ⇒tech
451コメント142KB

C++/TemplateMetaProgramming

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2008/02/16(土) 12:45:02
・ここはC++のテンプレートメタプログラミング専用スレです。
・なかったので立てました。
・前にもあったような気がするけど気にしない。
・次期C++(0x) boost STLの話題も、TMPに関係するならここにどうぞ。

仲良く使ってね。
0002デフォルトの名無しさん2008/02/16(土) 12:48:44
とりあえずTMP始めてだから優しくしてね><って人には
p_stabeのとこのブログのログを最初から読んだりしてみる事から始めるといい。
0003デフォルトの名無しさん2008/02/16(土) 12:49:15
すいません、やっぱり、該当スレでお願いします。
申し訳ありませんでした。
0004デフォルトの名無しさん2008/02/16(土) 12:49:55
おい>>1、メタだけあってもしょうがないだろ
何を話題にすりゃいいんだ
0005デフォルトの名無しさん2008/02/16(土) 12:50:02
>>1 乙
0006デフォルトの名無しさん2008/02/16(土) 12:50:48
>>4
いくらでも話題はあるさね
0007デフォルトの名無しさん2008/02/16(土) 12:51:13
>>4
template<fugafuga>を使った機能とか、
必要であればプリプロセッサも絡めてもらうとありがたいです。
0008デフォルトの名無しさん2008/02/16(土) 12:53:14
>>7
だったらテンプレートスレにしておけば良かったのでは・・・
なぜメタ限定?
0009デフォルトの名無しさん2008/02/16(土) 12:55:49
>>8
テンプレートスレならNTPとかMOJOばっかりで
Lispみたいなメタプログラミングは話題にし辛いだろう。
ここはそういうのを扱うスレ。コンパイル時点での、コードに対するプログラミングに関するスレ。
0010デフォルトの名無しさん2008/02/16(土) 12:59:04
>>8
激しく同意だな
でも、テンプレートスレじゃboost、STL、C++スレでカバーで良いんじゃね
0011デフォルトの名無しさん2008/02/16(土) 13:01:05
とりあえずPreprocessor Metaprogramming万歳
0012デフォルトの名無しさん2008/02/16(土) 13:02:02
メタプロと普通のテンプレート使ったプログラムは全然違うだろう。
0013デフォルトの名無しさん2008/02/16(土) 13:02:20
STLスレやboostスレとか何度も統廃合の話題が出てその度に荒れていたな
0014デフォルトの名無しさん2008/02/16(土) 13:02:53
スレが立った初っ端からいろいろ文句つけてる奴は何だ?
現在、板の各所に散らばっている“テンプレートスレ”で満足しているならこんな所覗く必要はないだろう。
“メタプログラミング”を話題にしたい奴がここを必要としているんだ。興味がないなら来るな。
0015デフォルトの名無しさん2008/02/16(土) 13:03:31
そうだそうだ
0016デフォルトの名無しさん2008/02/16(土) 13:04:05
いや、興味あるとかないとかそういう問題じゃねぇーだろw
0017デフォルトの名無しさん2008/02/16(土) 13:04:26
別にMetaProgrammingであればTemplateは必要なかったのでは?
誤解を招くだけだし。

あと、
>>1
>仲良く使ってね。
0018デフォルトの名無しさん2008/02/16(土) 13:05:07
メタプロが理解できない奴が嫉妬してクレーム付けてるだけだろ
0019デフォルトの名無しさん2008/02/16(土) 13:06:21
勢いが1234もある。
過疎ったVIPスレ並みに速い流れだな。その割には糞なレス多いけど。
0020デフォルトの名無しさん2008/02/16(土) 13:07:05
{
std::ofstream f( "tmp.cpp" ) ;
f << いろいろいろいろいろいろ ;
}
system( "cc tmp.cpp" );
system( "a.out" );
では、このあたりからw
0021デフォルトの名無しさん2008/02/16(土) 13:08:30
クラックしがいがありそうだなw
0022デフォルトの名無しさん2008/02/16(土) 13:10:44
>>20
テンプレート(ライブラリ)を使ったメタプログラミングだwww
0023デフォルトの名無しさん2008/02/16(土) 13:15:15
だいたい、>>1がアホだからいけないんだ
Templateなんて入れるないで、素直にC++/メタプログラミングすればよかった
0024デフォルトの名無しさん2008/02/16(土) 13:17:33
>8
Boost, STLとの統合の話題が出てくるからじゃね?
あっちは使い方、こっちは実装テクニックと使い分けできるといいね。

そういやポリシーってみんなどんぐらい使ってる?
template<class T> class M : public T {};
struct T1 { void t1() {}; };
struct T2 { void t2() {}; };
M<T1>().t1();
M<T2>().t2();
とか、インターフェースの差し替えが出来てけっこう便利な気がするんだけど。
0025デフォルトの名無しさん2008/02/16(土) 13:19:13
単純にテンプレートテクニックスレで良かったんじゃね、とか
0026デフォルトの名無しさん2008/02/16(土) 13:20:59
とりあえず同名の本の解答集
http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?CPP_Template_Metaprogramming_Book_-_Answers_Page

例えば演習2-3で型を文字列で出力するテンプレートを作りなさいなんて問題あるけど、
std::cout << type_descriptor<long const*&>();
これ、C++だと volatile, const, ポインタ、参照でそれぞれ specialization で場合分け
し、さらに基本型の int, long, char, double とかでさらに場合分け
とかなって、なんだか力業だなぁとか感じる(答参照)。
0027デフォルトの名無しさん2008/02/16(土) 13:22:12
>>24
スーパークラスに直接Tをいれるのはコンパイルが異様に重くなるので最近は避けているな。
0028242008/02/16(土) 13:27:07
>27
エエエ(ry
コンパイルなんて昔に比べると激早だから、あんまり気にしないなあ。
どちらかというと使う側でpimplとかの工夫してるし。
0029デフォルトの名無しさん2008/02/16(土) 13:28:41
そおか、C++以外の言語を使ったあとだと余りの遅さにかなりショックを受けるんだが。
0030デフォルトの名無しさん2008/02/16(土) 13:34:03
100ファイル程度あると、C++は自作オーバークロックの最強マシンをもってして三十分や一時間かかりかねないけれど
これがC#だとヘナチョコマシンでも一分掛かるか掛からないかといった所。
0031デフォルトの名無しさん2008/02/16(土) 13:37:46
コンパイル時間のほとんどは
プリプロセスなんだろうなあ。
0032デフォルトの名無しさん2008/02/16(土) 13:48:27
>>30
どう考えてもそれは長すぎる
せいぜいかかっても1ファイルに2〜3秒ってところじゃないの?
0033デフォルトの名無しさん2008/02/16(土) 13:48:37
Boost.Lambdaのヘッダをプリコンパイルドヘッダに入れようとすると、
pchがぶくぶく膨らんでいく。

後のコンパイルでは、プリコンパイルドヘッダの読込も
ボトルネックになっているのではという気がしてならない。
0034デフォルトの名無しさん2008/02/16(土) 13:50:18
>>31
よほど凝ったことしなきゃそれはないだろ
0035デフォルトの名無しさん2008/02/16(土) 13:51:20
プリコンパイルでどれだけの時間が短縮されるか考えたら
そんなもんだと思う
0036デフォルトの名無しさん2008/02/16(土) 13:52:37
プリコンパイルは一応コンパイルもしてるわけで
0037デフォルトの名無しさん2008/02/16(土) 13:55:07
>33
ヘッダを重くするとそうなるけど、それこそpimplで隠したら?

Boost.Lambdaをヘッダに突っ込もうとする時点で何か設計で失敗している気がするけど。
#ライブラリを設計しているのならしょうがないけど
0038デフォルトの名無しさん2008/02/16(土) 13:59:49
$ cat test.cpp
# include <boost/lambda/lambda.hpp>

int main()
{
using namespace boost::lambda;
int i = 4;
return (_1 + _1 + 1)(i);
}
$ time g++ test.cpp

real 0m1.175s
user 0m0.900s
sys 0m0.068s
$ time cpp test.cpp >/dev/null

real 0m0.249s
user 0m0.160s
sys 0m0.024s
0039デフォルトの名無しさん2008/02/16(土) 14:03:25
>>37
たしかにLambda自体は特定のcppファイルでしか使っていない。
こういうときはプリコンパイルドヘッダから外すべきなのか?
0040デフォルトの名無しさん2008/02/16(土) 14:05:43
そらそうだな。
0041デフォルトの名無しさん2008/02/16(土) 14:09:20
>39
ヘッダは基本的にインターフェイスなんだから、インターフェイスに不要な実装は隠すのが望ましい。
テンプレート使ってるとそんなことも言ってらんないけど。
0042デフォルトの名無しさん2008/02/16(土) 14:16:12
そろそろC++という言語自体を見直すのが望ましいという気もしないでもない
問題累積しすぎだろ
0043デフォルトの名無しさん2008/02/16(土) 14:19:31
>>41
stdafx.hで何もかもインクルードしていたよ。
0044デフォルトの名無しさん2008/02/16(土) 14:32:12
以前のスレを探してきた。

【C++】template 統合スレ -- Part6
http://pc8.2ch.net/test/read.cgi/tech/1101384692/
0045デフォルトの名無しさん2008/02/16(土) 14:49:06
ある程度確定したクラス他は専用libに放り込んでるので無問題
0046デフォルトの名無しさん2008/02/16(土) 14:58:08
・クラス単体のみの宣言だけ
 class A;
・クラスのインターフェイスを含めた宣言だけ
 class A{ void f(); };

2種類のヘッダを用意すれば(ry
0047デフォルトの名無しさん2008/02/16(土) 16:28:15
>41
C++狂Herb Sutterの本を読んだほうが良いと思う。
ヘッダファイル: インターフェイスに関係するファイルを最低限
ソースファイル: できるだけこっちでインクルードする
が基本だよ。
0048デフォルトの名無しさん2008/02/16(土) 16:31:58
コンパイル時間の節約は分かるんだが、
いざヘッダファイルをインクルードして何か使おうとすると
実装が無いとか文句言われることがあるのが困るんだよな。
0049デフォルトの名無しさん2008/02/16(土) 16:32:21
実装じゃねえや。定義だ。
0050デフォルトの名無しさん2008/02/16(土) 16:33:06
>>48
ただの誤用にしか聞こえんのだが、どういう状況の話?
0051デフォルトの名無しさん2008/02/16(土) 16:39:01
不完全型のみで十分な状況では
その型を定義してあるヘッダをインクルードせず、
不完全型の宣言のみを書く。
そして、その型を使ってるソースファイルでのみ、
そのヘッダファイルをインクルードする。
0052デフォルトの名無しさん2008/02/16(土) 16:59:36
なんかC++の基本もまともに出来ないような人が居ますね。
0053デフォルトの名無しさん2008/02/17(日) 02:18:38
TMPやるにはHaskell勉強した方が良いって本当ですか?
0054デフォルトの名無しさん2008/02/17(日) 02:20:47
>>53
変数への代入ができないという制約の下でどうやって問題を解決するかを学ぶ、
という点で本当だと思う。
0055デフォルトの名無しさん2008/02/17(日) 10:28:54
SICP読んだらModern C++ Designが分かった
0056デフォルトの名無しさん2008/02/18(月) 13:01:03
Scheme勉強したらModern C++ Designが分かった
0057デフォルトの名無しさん2008/02/18(月) 13:47:54
あれって別の関数型言語を勉強してからじゃないと理解できないほど難しいか?
0058デフォルトの名無しさん2008/02/18(月) 13:59:44
ムチャクチャな書き方をしないといけないからわかりにくいんだよ。
すっきりした表記の関数型言語を勉強した後だと
どういうトリックなのかがすんなり理解できる。
0059デフォルトの名無しさん2008/02/18(月) 14:01:52
別に無茶苦茶ではないと思うが。
0060デフォルトの名無しさん2008/02/18(月) 14:54:27
再帰に継承が絡んでくると難しく感じる。
0061デフォルトの名無しさん2008/02/18(月) 14:56:58
慣れてないだけだな。それにあんなもの別にC++以外のものを触ったって慣れやしない。
0062デフォルトの名無しさん2008/02/18(月) 15:32:39
ところで>>2のp_stabeには誰もつっこまないの?
p_stadeじゃないかって
0063デフォルトの名無しさん2008/02/18(月) 15:37:29
q_stabe
0064デフォルトの名無しさん2008/02/18(月) 16:57:57
>>61
それは違うと思う。関数型言語のほうが記法が簡便だが抽象度が高く
センスが必要。LispでもSchemeでも自在に扱えればC++のメタなんて少し
の時間でマスターできる。templateなんて少しの時間でマスターできる。
経験上確信してる。逆は成立しない。
0065デフォルトの名無しさん2008/02/18(月) 17:19:20
千差万別、十人十色
自論に固執すること愚か也
0066デフォルトの名無しさん2008/02/18(月) 17:32:39
言語に組み込まれてるってのは重要だよな。

C++だとマクロとかでちょっと文法の解釈を脳内変換すれば
いいんだけど手間が増大するのと
初学者に扱える代物ではなくなってしまうんだよね。
0067デフォルトの名無しさん2008/02/18(月) 18:10:14
>>65
関数型言語の経験ないだろ?
0068デフォルトの名無しさん2008/02/18(月) 18:10:49
>>65
SICPは読んだ?
0069デフォルトの名無しさん2008/02/18(月) 18:25:10
負けへん、負けへん
山ちゃんは負けへんでええ
0070デフォルトの名無しさん2008/02/18(月) 18:25:39
誰か質問しろよ。
スレ落ちるの時間の問題だな。
0071デフォルトの名無しさん2008/02/18(月) 18:30:41
C++0xではmplは入らなくてTypeTraitsどまりってことは
mplはまだ重視されてないってこと?メイヤーズの本では
TMPがC++の中心に来ることはないなんて書いてあったけど
どうなんだろ?
0072デフォルトの名無しさん2008/02/18(月) 19:20:00
そうなんでしょう。
だって頭の体操にはなるけど、あんまり実用性ないじゃん。
0073デフォルトの名無しさん2008/02/18(月) 19:27:11
type_traitsはフレームワークであって、
みんなが自分のクラスのtraitsを提供しないと真価を発揮しないけど、
mplは使いたい人が使えばいいだけだから標準化しなくても困らない。
0074デフォルトの名無しさん2008/02/18(月) 19:38:50
C++0x において提案されている <type_traits> で提供される機能の中には
コンパイラが持っている独自の情報を吐いてくれないと実装できないものも多いので
そういう意味で TypeTraits は優先的に規格として明示してくれないと困るかと
0075デフォルトの名無しさん2008/02/18(月) 19:40:35
call_traits は追加されるの?
0076デフォルトの名無しさん2008/02/18(月) 20:41:26
MP専用の構文を入れる気はもうないのかね

Templateでできたのはたまたまであって、
いつまでもあんなハックみたいな書き方したくないなぁ
0077デフォルトの名無しさん2008/02/18(月) 23:08:07
バッドノウハウ
0078デフォルトの名無しさん2008/02/19(火) 02:44:27
完全体のC++かどうかを判断するために
compiler_traits
が必要な気がする。

0079デフォルトの名無しさん2008/02/19(火) 02:49:56
そうなるとまず has_compiler_traits が必要だな。
0080デフォルトの名無しさん2008/02/19(火) 21:01:07
>>76
D言語の出番ですね、分かります
0081デフォルトの名無しさん2008/02/19(火) 23:57:02
いやあ、すべってるねえ このスレ
0082デフォルトの名無しさん2008/02/20(水) 00:07:56
昔ProgramingJemsにメタプログラミングでsinテーブルを生成するっていうネタがあった

当時メタプログラミングなんて知らなくて、
「すげぇぇぇぇ」と感動して自分でも作ってみた

しかし当時のオレのショボマシンではコンパイル時のサインテーブルの生成に結構な時間がかかり
最終的に、
Perlでテーブル書いたソースジェネレートした方が早くね?
という結論に
0083デフォルトの名無しさん2008/02/20(水) 00:13:14
メタプログラミングとは?

テンプレート、型、typedef、コンパイル時定数、再帰を
駆使したコンパイル時プログラミングで合ってる?
0084デフォルトの名無しさん2008/02/20(水) 00:15:48
テンプレートメタプログラミングならそれでまあ合ってる。
0085デフォルトの名無しさん2008/02/20(水) 00:18:10
>>83
それはテンプレートメタプログラミングの説明だな
メタプログラミング自体はもっと広く、プログラムを操作するプログラム全般をいう
プリプロセッサを使うのもメタプログラミングだし、コードジェネレータを書くのも含む
0086デフォルトの名無しさん2008/02/20(水) 00:20:22
テンプレート抜けてた。
0087デフォルトの名無しさん2008/02/20(水) 00:43:39
そういう意味では82のPerlでソース生成と言うのも立派なメタプログラミング。
0088デフォルトの名無しさん2008/02/20(水) 01:04:07
>>82
そんなあなたに constexpr@C++0x
0089デフォルトの名無しさん2008/02/20(水) 01:06:00
一方D言語はsinを定数として畳み込んだ。
0090デフォルトの名無しさん2008/02/20(水) 01:09:59
静的に実行できる関数は静的に実行してしまう。
D は中々のものだ。
0091デフォルトの名無しさん2008/02/20(水) 01:35:24
D言語って誰が生みの親なの?
0092デフォルトの名無しさん2008/02/20(水) 01:36:25
昔borlandで働いてた人
0093デフォルトの名無しさん2008/02/20(水) 01:37:28
をるたん
0094デフォルトの名無しさん2008/02/20(水) 01:40:52
>>92
じゃあ流行らないな
0095デフォルトの名無しさん2008/02/20(水) 01:43:40
ボーランドはちがくね?
0096デフォルトの名無しさん2008/02/20(水) 18:26:21
>>82
まあC++のテンプレートはメタプログラミングのために設計されてないからねえ。
マクロらしいマクロを持った言語なら、かなり高度なメタプログラミングをやってても
普通のコードの2倍やそこらの時間でコンパイルできる。
Lispの世界じゃ40年前からメタプログラミングが当たり前だし、
DOSの世界ではMASMのマクロで構造化なんてのが流行った。
0097デフォルトの名無しさん2008/02/20(水) 18:35:23
ライブラリ作るときは主流になりそうだけどな。
てか、もうなってるか。
でもschemeのほうが言語機能としてcons listとか
があるから、より簡潔でストレス感じない。
C++のTMPはいかんせん表現がキモ過ぎる。
0098デフォルトの名無しさん2008/02/20(水) 21:15:57
そこで constexpr ですよ
0099デフォルトの名無しさん2008/02/22(金) 02:22:19
こんなの作ってみた。
自分のプログラムでは活用できてるからいいんだけど、意外と汎用性ないな……

struct UniqueNumber {
   template<class type_t>
   static unsigned int number() { static unsigned int n(count()); return n; };
private:
   static unsigned int count() { static unsigned int c(0); return c++; };
}
0100デフォルトの名無しさん2008/02/23(土) 01:51:48
>>83
プログラムを作るプログラムをプログラムしてみようって事だよ
当然、(プログラムをつくるプログラム)をつくるプログラムもね。
どこまででも逝ってくれ
0101デフォルトの名無しさん2008/02/25(月) 16:49:57
>>99
typeidの速度が気になる場面で使うのかな?
0102デフォルトの名無しさん2008/02/25(月) 17:07:03
>>99
struct UniqueNumber {
static unsigned int number() { return count(); }
private:
static unsigned int count() { static unsigned int c; return c++; }
}

これでよくない?
0103デフォルトの名無しさん2008/02/25(月) 17:09:25
>>102
全然よくない。
0104デフォルトの名無しさん2008/02/25(月) 17:13:44
>>103
何で?
type_tテンプレートパラメータ使われてないよ。
0105デフォルトの名無しさん2008/02/25(月) 17:16:00
>>104
UniqueNumber::number<A>()とかUniqueNumber::number<B>()みたいな使い方するんでしょ。
で、テンプレートに渡した型毎に一定のユニークな値が返ってくると。
0106デフォルトの名無しさん2008/02/25(月) 17:33:05
ああそうか

でも
cout << UniqueNumber::number<int>() << endl;
cout << UniqueNumber::number<int>() << endl;
cout << UniqueNumber::number<int>() << endl;
cout << UniqueNumber::number<char>() << endl;
cout << UniqueNumber::number<char>() << endl;
cout << UniqueNumber::number<float>() << endl;

やったら
0 0 0 1 1 2
となった。
何で、0 1 2 0 1 0にならないのかな?
01071062008/02/25(月) 17:38:05
わかりますた。なるほど。
0108992008/03/01(土) 03:50:23
応用例作ってみた。
ttp://fiercewinds.net/siki/pub/2008/03/01_032951/
継承で登録を強制できれば便利そうなんだけどなぁ。
あとファクトリ関数みたいに関数の引数とか戻り値にそのクラスを含む場合は、こんな大掛りな仕掛けは不要みたい。

……それ以前に言語側で何とかして欲しいよな。こんなの。
0109デフォルトの名無しさん2008/03/15(土) 21:46:47
ちょっと質問です。
外部リンケージについて詳しく書いてある解説ってある?
具体的には関数内クラスをテンプレートパラメーターにして渡したいんだけどね。
externでも上手く行かんし……
0110デフォルトの名無しさん2008/03/15(土) 21:51:35
それはそもそも無理じゃまいか?
01111062008/03/15(土) 22:19:26
>>109
規格上不可能
0112デフォルトの名無しさん2008/04/10(木) 23:41:05
メタプログラミングしてると脳汁でます
0113デフォルトの名無しさん2008/04/11(金) 00:39:33
なぜjavaやC#でtemplateが外されたか
不要物だからw
0114デフォルトの名無しさん2008/04/11(金) 00:58:20
なぜJavaやC#でgeneri(ry
0115デフォルトの名無しさん2008/04/11(金) 01:01:28
失ってから大切さに気付くものです
0116デフォルトの名無しさん2008/05/07(水) 22:32:52
boost::mplとか使ってるコードで見る、
_1, _2ってどうやって実現してるんですか?
0117デフォルトの名無しさん2008/05/07(水) 22:35:39
ソース読めばいいだろw
0118デフォルトの名無しさん2008/05/07(水) 23:07:19
defineかtypedefだったかな
0119デフォルトの名無しさん2008/05/09(金) 15:11:22
テンプレートで配列指定された場合エラーにする方法ってあるんでしょうか?
0120デフォルトの名無しさん2008/05/09(金) 18:55:50
type_traitsのis_arrayとBOOST_STATIC_ASSERTを組み合せればいけるはず
0121 2008/05/14(水) 07:27:15
g++とVC2008どっちがテンプレート学ぶにはいいですか?
どっちがより完璧にテンプレートをコンパイルできますか?
0122デフォルトの名無しさん2008/05/14(水) 07:35:58
どうみてもg++
0123 2008/05/14(水) 09:16:34
>>122
ありがとう。
0124デフォルトの名無しさん2008/05/19(月) 02:14:25
テンプレートの実体化でテンプレート引数を特殊化にマッチさせる過程って
Prologの統一化と似てる気がする
0125デフォルトの名無しさん2008/06/01(日) 02:40:06
>>99
のような型にユニークな数字を割り当てるのをコンパイル時にできないでしょうか?
boost::fusion::vectorに格納されている型をすべてユニークな型にしたいとき、
単純に片っ端から同じ型が含まれていないか調べると計算量がO(n*n)(nは格納されている型の数)になるかと思います。

そこで、boost::fusion::vectorをboost::mpl::sortしてboost::mpl::uniqueすれば
sortが平均O(n*log(n)), uniqueがO(n)だとすると先に説明した単純な方法より高速に計算する事ができるかと思います。

ですが一般的な型に対して順序関係はないのでboost::mpl::sortを実行することができません。
そこで>>99のような型毎に静的にユニークな数字を割り当ててboost::mpl::sortを適応させることができるようにしたいです。

長くなりましたが、皆様宜しくお願いします。
0126デフォルトの名無しさん2008/06/01(日) 04:09:25
ムリじゃない?
分割コンパイルみたいな局面を考えると、ある型にユニークな数字が割り当て済かどうかすら判らんと思う。
リンカと連携すればいいんだろうけど、C++の規格はそこまで考えてないんじゃない?

指定された型のstaticポインタを用意してそのアドレスを使えばなんとかなるかも知れんが、どうなんだろ?
void*にキャストすれば比較もできるんじゃね?
0127デフォルトの名無しさん2008/06/01(日) 18:57:02
そもそも数字の割り当て方を制御できないとソートする意味がなくね?
どう割り当てたいの?
0128デフォルトの名無しさん2008/06/01(日) 19:09:24
どんな数値でもいいから割り当ててしまえば二分探索の恩恵を受けられるってことだろ
0129デフォルトの名無しさん2008/06/02(月) 02:49:12
>>126
やはり無理なんですかね。
アドレスを得られるのはコンパイルのテンプレートの展開等の後の段階になるので無理だと思うのですが。

>>127
>>125で書いてある通り,型の集合の中に同じ型が含まれないようにすることが目的なので
boost::mpl::uniqueする前に同じ型が連続して並ぶようにboost::mpl::sortの結果が返ればよいのです。
ですので割り当てたい数字は型毎にユニークであれば何でもよいのです。アドレスもOK養豚場です。

>>128
二分探索を使って同じ型を消す処理をしてもO(n*log(n))で計算できそうですね。
そういう方法は考えていませんでした。
0130デフォルトの名無しさん2008/06/02(月) 03:18:17
>>125
で書いた事をもう少しわかりやすく説明すると
例えば以下のような型があったとき、
typedef boost::fusion::vector<char, int, char, int> vec;
vecから重複する型を削除してユニークな型を保持するようにしたいのです。
typedef hoge<vec>::type unique_vec; //こんなhogeを欲しているのです.
BOOST_MPL_ASSERT(( boost::is_same<unique_vec, boost::fusion::vector<char, int> > ))

それで、以下の仮想コードのような方法を使とO(n*n)の計算時間が掛ります.
for i∈vec
 for j∈vec
  もしiとjが同じ型だったらjをvecからはずす.

そこで
typedef
boost::mpl::unique<
 boost::mpl::sort<
  vec, piyo>::type,
 is_same<_1, _2> >::type
unique_vec;
とやればO(n*log(n))の計算量で済みます。
そこで上記のpiyoに相当するMetafunction class、
すなわち型に順序関係を与える方法を教えて貰いたいのです。

>>128
referenceにはboost::mpl::findは線形時間が掛ると書いてあるので
二分探索するには自分でコードを書かないといけないようです.
0131ヽ・´∀`・,,)っ━━━━━━━┓2008/07/09(水) 14:39:37
>>124
静的(コンパイル時完全評価)だけどな。

VIPのスレで昔テンプレートでアッカーマン関数の問題解こうとしてドツボにハマった奴がいた。
0132デフォルトの名無しさん2008/07/16(水) 20:46:07
『Modern C++ Design―ジェネリック・プログラミングおよびデザイン・
パターンを利用するための究極のテンプレート活用術 (C++ In‐Depth Series) 』

ってのを読んでいる素人だけど、69ページのMostDerivedってのが
マジ分からん。今日、朝、昼、晩を合計で4時間ぐらい考えたんだが
どういう流れでこれで継承関係でいちばんの派生なのを特定できるのか
分からん。誰か分かる人いませんか?
0133デフォルトの名無しさん2008/07/16(水) 21:05:22
結局、
typedef typename MostDerived<Tail, T>::Result Candidate;
では、再帰的に展開が繰り返され、MostDerived<NullType, T>に
なり、CandidateはTにしかなりえない

続く、
typedef typename Select<
SUPERSUBCLASS(Candidate, Head),
Head,
Candidate
>::Result ResultではCandidateはTと読み替えられるわけで

TがHeadのスーパークラスなら結果はHead
HeadがTのスーパークラスなら結果はTとなる

これじゃ全然ダメじゃね?

ググってみたけど、MostDerivedはダメだったって話を他でも見かけたよ
0134デフォルトの名無しさん2008/07/26(土) 05:07:27
>133
>typedef typename MostDerived<Tail, T>::Result Candidate;
>では、再帰的に展開が繰り返され、MostDerived<NullType, T>に
>なり、CandidateはTにしかなりえない

どの段階で T にしかなりえないと思ってるのか分からないけどちゃんと再帰的に展開できてる?
MostDerived<TypeList<T0, TypeList<T1, NullType> >, T>::Candidate
# Head=T0, Tail=TypeList<T1, NullType>
→MostDerived<TypeList<T1, NullType>, T>::Result
# Head=T1, Tail=NullType
→Select<SUPERSUBCLASS(MostDerived<NullType, T>::Result, T1), T1, MostDerived<NullType, T>::Result>::Result
# MostDerived<NullType, T>::Result → T
→Select<SUPERSUBCLASS(T, T1), T1, T>::Result

結果として、
MostDerived<TypeList<T0, TypeList<T1, NullType> >, T>::Result
→Select<SUPERSUBCLASS(Select<SUPERSUBCLASS(T, T1), T1, T>::Result, T0), T0, Select<SUPERSUBCLASS(T, T1), T1, T>::Result>::Result
T と T1 を比較した結果、と T0 を比較した結果が返ってくる。
0135デフォルトの名無しさん2008/08/30(土) 14:17:24
ttp://www.fides.dti.ne.jp/~oka-t/cpplab-tips-1.html に
ローカルクラスの静的関数は関数テンプレートの引数に指定可能というのがあるのですが、
ローカルクラスのクラス内クラスの場合どうなりますか?
役立たずVC8だとノーチェックでOKにしたので確認できませんでした。
void func() {
   struct local {
      void operator()(int x) { cout << x << endl; }
      static void f( int x ) { cout << x << endl; }
      struct func {
         void operator()(int x) { cout << x << endl; }
      };
   };
   std::vector<int> v;
   v.push_back(0);
   v.push_back(1);
   v.push_back(2);
   for_each( v.begin(), v.end(), local::f );
   for_each( vbegin(), v.end(), local::func() );  // これはどうなるの?
   for_each( v.begin(), v.end(), local() ); //ホントはエラーのはず。VC8.0はOK……
}
0136デフォルトの名無しさん2008/08/30(土) 15:00:49
VCだと言語拡張を有効にすることで関数内構造体もテンプレート引数に渡せてしまう。
俺はそれが嫌で言語拡張を無効にしてる。
0137デフォルトの名無しさん2008/08/30(土) 16:07:38
>136
サンクス。無効にすると両方ともNGになりますね。
言語拡張を無効にすると色々なライブラリが使い物にならなくなるから、
さすがにそこまでストイックにはなれないなぁ……
0138デフォルトの名無しさん2008/08/31(日) 17:08:18
言語拡張機能が使用された場合に警告を出すってオプションがあったと
思うんで、取り合えずそれONにしとけば?
0139デフォルトの名無しさん2008/08/31(日) 17:37:41
そんなもの存在しません。
0140デフォルトの名無しさん2008/10/14(火) 17:41:25
工エエェェ(´д`)ェェエエ工工
0141デフォルトの名無しさん2008/10/18(土) 22:01:41
template <template <class Created> class CreatePolicy>

これのtemplate <class Create>部分の採用がヨクワカラナイ
どこかに良い説明のってないっすか
0142デフォルトの名無しさん2008/10/19(日) 02:40:29
とりあえず検索用語だけ
template-template-parameters
0143デフォルトの名無しさん2008/10/24(金) 23:27:12
class Hoge {
template <int X> void Fuga() {...}
};

テンプレート引数Xの値を、静的な値として集めることってできますか?
具体的には、呼び出されたFugaのうち、最も大きいXを取得して、別のクラステンプレートに渡すとか。
0144デフォルトの名無しさん2008/10/26(日) 01:21:18
>>143
パッとみて無理っぽいうえにコンパイル単位をまたぐ場合を考えるとさらに無理っぽい。
0145デフォルトの名無しさん2008/10/30(木) 20:35:00
(´;ω;`)
0146デフォルトの名無しさん2008/11/26(水) 04:36:26
>>142
横だけど、meta templateでググっても見つからなく困っていたので助かった。
そういう用語だったのか…
0147992009/01/12(月) 20:40:07
まいど。

どうしても欲しくなったのでマルチメソッドを実装したんだけど、もっと効率的になる改善点てあります?
(詳細)ttp://cvs.sourceforge.jp/view/siki/siki/src/holder.hpp?rev=1.1&view=markup
(解説)ttp://fiercewinds.net/siki/pub/2009/01/12_191240/
解説がクソなのは置いといて下さい。

もっと良い実装があればそれも紹介して欲しいです。

個人的には
・いちいち登録しなきゃいけないのが面倒。
・トランポリン関数を保持する配列が疎になるのでメモリ効率が悪そう……
というところが気になるところです。

0148992009/01/13(火) 00:44:59
ちょっとだけ >147を修正。
登録をヘルパークラスに任せることにしました。少しはスマートに見えるけど、受け入れる型を
全部登録しなきゃいけないのは変わらず……

色々と考えてみたけど、どうやっても仮想関数に型情報は渡せなさそうね……。
0149992009/01/13(火) 01:15:20
リンク間違えてたので修正します。
(詳細)ttp://cvs.sourceforge.jp/view/siki/siki/src/holder.hpp?view=markup
0150デフォルトの名無しさん2009/01/19(月) 20:24:39
ポリシーによるプログラミングで質問です。
適当な乱数を発生させるTraitsクラスを何個か定義します。
 struct r {int rdm(){return rand()%128;}};
 struct rs{int rdm(){return rand()%7+60;}};
そんで、Traitsを使うクラスがこれ。ここまでは順調です。
 template <class T=r> class R{int rdm(){return T.rdm();}};

この後、rdm関数が引数を持つようなTraitsを加えようとすると型があわないため困りました。
しかし、こういうケースは良くあるのではないかと思います。
 struct rc{int rdm(int n){return n*(rand()%128);}

少し悩んでこんな解を出して見たのですが
こういう場合、みなさんどのように解決されますか?
template <int N> struct rt{int rdm(){return N*(rand()%128);}
R<rt<3> > r;
↑この場合、途中で引数を変えたいと思った場合毎回インスタンスを作る必要がある点が若干面倒です。
また、整数引数しか使えません
関数でやる場合は引数変更は楽ですが
Traitsにあたるものが増えてくると関数の組み合わせ爆発が大変です。
手法にこだわりはないのでこのやり方が楽、などあればきいてみたいです。
0151デフォルトの名無しさん2009/01/19(月) 20:35:21
struct r{ int rdm(){ return rand() % 128; } };
struct rs{ int rdm(){ return rand() % 7 + 60 } };
template<typename Ty> struct rc{ Ty value; int rdm(){ return value * (rand() % 128); } };
後はrc::valueのゲッター書くなりセッター書くなりしろ。
01521502009/01/19(月) 21:33:25
>>151
ありがとう。参考にします。
0153デフォルトの名無しさん2009/01/19(月) 23:44:40
STL コンテナでアロケータを指定する方法を真似するのは、何か都合が悪いの?

template <class T=r > struct R {
 T t;
 R( const T & t_ = T() ) : t(t_) {}
 int rdm() { return t.rdm(); }
};

R< random_with_number > rn( random_with_number(3) );
0154デフォルトの名無しさん2009/01/24(土) 14:16:13
>>153
これは良いですね!頂きます。
使ってみて、若干罠というか、引数なし版はプロトタイプ宣言と勘違いされるため
 R<r> a(r()); //error
こうする必要があるんですね(もっと良いやり方があるのかは知らないですが・・)
 R<r> b(*(new r()));

これを参考に、少し書き換えて見ました
struct b {virtual int rdm(){return 0;}};
struct r:b {int rdm(){return rand()%128;}};
struct rs:b{int rdm(){return rand()%7+60;}};
struct rc:b{
int val;
rc(int n) : val(n){}
int rdm(){int tmp=rand()%7;if(tmp%val==0){return tmp;}else{return rdm();}}};

template <class T=b > struct Q {
T* t;
Q( T* t_) : t(t_){}
int rdm() { return t->rdm();}
};
Q<> a(new rc(3));
Q<> b(new r());
0155デフォルトの名無しさん2009/01/24(土) 14:55:23
>>154
>  R<r> a(r()); //error
R<r> a((r()));
でいけるよ
0156デフォルトの名無しさん2009/01/24(土) 15:15:23
ほんとだ、こっちのが短くていいですね。
0157デフォルトの名無しさん2009/01/24(土) 15:27:24
struct b::rdm() を virtual にするなら template にする意味は無いと思うのだけれども・・・。

struct Q { // non template version
 b * t;
 Q( b * const t_) : t( t_ ? t_ : new b ){}
 ~Q() { /* Do you want to delete t ? */
 int rdm() { return t->rdm();}
};
でいいでしょ。

ポインタじゃなくて、値のコピーのほうが、いろいろいいよ。
0158デフォルトの名無しさん2009/01/24(土) 16:08:53
単に左辺を書かなくても良くなるぐらいの気持ちで書き直したんですが
そもそもtenmplate無くても動きますね・・難しいなぁ
ある意味、template使わなくてもポリシーベースのプログラミングが出来るわけですね
あえてtemplateを使う利点が整理できてないので考えてみます。

>ポインタじゃなくて、値のコピーのほうが、いろいろいいよ。
シンプルながら、これは説得力ありますね
0159デフォルトの名無しさん2009/01/24(土) 16:43:24
>>155-156
R<r> a;でいいじゃない。
01601572009/01/24(土) 17:11:30
>>158
> あえてtemplateを使う利点が整理できてないので考えてみます。
157 では、t->rdm() は、コンパイラによって必ず仮想関数呼び出しコードが出力される。
テンプレートバージョンでは、定数を返す場合などには、もしかしたらコードは全く無くなるかもしれない。
153 程度で大げさな、と思うかもしれないが、これもメタプログラミングだ。
実行時に通過するコードではなく、コンパイルで出力されるコードを、引数で変えることが出来るから。
C のプリプロセッサマクロでも出来るけど、C++ template は型チェックとそこから派生する特殊化された型の選択が強み。

> シンプルながら、これは説得力ありますね
157 の Q のデストラクタを見てみて。
あと、メモリ消費量が減るかも。


ところで、154 の記法の問題は、cl, bcc, gcc で試したけど、
 R<r> a( (r)r() );
が一番互換性が高いようだ。
もちろん 159 でいいんだけどw 引数を明示したいならね。
0161デフォルトの名無しさん2009/01/24(土) 18:32:50
> R<r> a( (r)r() );

たまたま‘r’という短い名前だからそれでいいかもしれんが、
名前が長かったり、さらにネストしたテンプレートクラスだったりすると
書くのも面倒だよ。

他にも
 R<r> a = R<r>(r());
とか考えられるけど、やっぱり
 R<r> a((r()));
が楽だと思うけどね。
0162デフォルトの名無しさんNGNG?2BP(0)
age
0163デフォルトの名無しさん2009/03/12(木) 22:20:49
テンプレートの引数にテンプレート渡せるのか〜知らなかった。
これで大分やれることが広がったぜ。ウヒヒ
ていうか、テンプレートの完全な仕様ってどこに行けばみれるの?
0164デフォルトの名無しさん2009/03/12(木) 22:27:47
>>163
ちょうどこっちでその話があったところ。
http://pc11.2ch.net/test/read.cgi/tech/1234420483/758-767
0165デフォルトの名無しさん2009/04/06(月) 19:01:46
Modern C++ Design(和訳)の正誤表を確認したいのだけど、どこかにないかな?
ぐぐると↓のURLらしいが、今はアクセスできないようだ・・。

http://www.biwa.ne.jp/~mmura/ModernC++Design/errata.html
0166デフォルトの名無しさん2009/04/06(月) 20:06:32
http://erdani.org/errata/
0167デフォルトの名無しさん2009/04/06(月) 20:20:17
>>166
う〜ん、そこからのリンクも切れてるなぁ。
http://www.biwa.ne.jp/~mmura/ModernC++Design/index.html
0168デフォルトの名無しさん2009/04/06(月) 20:28:42
ttp://web.archive.org/web/*/http://www.biwa.ne.jp/~mmura/ModernC++Design/index.html
0169デフォルトの名無しさん2009/04/06(月) 21:05:05
>>167
>う〜ん、そこからのリンクも切れてるなぁ。
これでリンクが切れてるなんて言うお前に、Modern C++ Design rokiは無理
0170デフォルトの名無しさん2009/04/06(月) 21:08:12
Loki とroki さてどっちでしょう
>>165には関係ない話題ですがww
0171デフォルトの名無しさん2009/04/06(月) 21:28:26
流れを気にせず好き勝手に意見を述べるが
先に関数型を勉強してからMC++Dを読む方が
すっきり理解出来る気がする

要は、既に確立した技術をC++に応用したわけだが
このロシアおっさんのとんでもない所は
要素技術とでも言うべき箇所、
例えば...やらsizeofの評価順序やら型としてのstructやらを
C++の仕様から見つけ出したところだと思うわ。
コンパイラが対応してない時代にどんだけ仕様把握してるんだよ
パねぇっす
宇宙ヤヴァイの改変コピペが作りたくなるぐらい。
0172デフォルトの名無しさん2009/04/06(月) 21:45:55
でもconceptがまともに使えるようになるまでC++でプログラミングしたくないよねーってなるよ
0173デフォルトの名無しさん2009/04/06(月) 22:22:49
少年アシベで
アイスをねだるゴマちゃんに
豆腐を与える静的なダックタイピング

structuralなポリモフィズムのことだっけ?
C++0xでたら考えよう。それまでは関数型で遊んでる

ところで、ポリシーによるプログラミングが
綺麗に適用出来るケースって、結構少ない気がするんだ
AがB/C/Dで代替出来るケースよりも
AがA(B)やA(B(C))で代替とするケースのほうが
プログラミングしてて多いように感じる
01741672009/04/07(火) 03:26:42
>>168
助かったよ。ありがと。
0175デフォルトの名無しさん2009/04/07(火) 03:30:43
>>171
たしかにlambdaとかbind(束縛)なんて単語に馴染みあるかないかでも理解スピードは
違うだろうな。

つかなんで無理やりC++でここまで頑張るのか不思議だ。
0176デフォルトの名無しさん2009/04/10(金) 12:34:36
暇なんだろ
0177デフォルトの名無しさん2009/04/12(日) 21:54:11
boostのlambdaは、確かに実用性に欠ける
あれの意味不明なエラーメッセージと格闘してる暇があるなら
普通に関数オブジェクト作った方が早い
0178デフォルトの名無しさん2009/04/12(日) 23:23:17
書いてる段階でエラーに気づかないほど複雑なものをboost::lambdaで書こうとするのが間違い。
0179デフォルトの名無しさん2009/04/13(月) 00:15:53
そもそもC++で関数型をやるのが間違い
0180デフォルトの名無しさん2009/04/13(月) 04:44:23
C++0x!はやくきてくれー!
0181デフォルトの名無しさん2009/04/28(火) 21:51:49
永遠にこないでくれ

by 製品コンパイラ開発者
0182デフォルトの名無しさん2009/04/29(水) 12:40:40
その程度のコンパイラ開発者なら要らん。
0183デフォルトの名無しさん2009/08/12(水) 01:02:13
そうです TMPは導入されたのではありません
発見されたのです!
0184foi.americanprogress.org2009/08/17(月) 17:49:45
自動焼人 ★ = 自動保守 ◆KAWORUKOFI = 自動保守#K9K?_D[L

名言集 その4
『俺、100人規模の集団サイバーテロの主犯だったこともあるんだぜ』

http://yutori7.2ch.net/test/read.cgi/news4vip/1249830540/ のID:PVAf+dux0 = 自動焼人 ★

> 965 :以下、名無しにかわりましてVIPがお送りします [sage] :2009/08/10(月) 00:02:09.35 ID:PVAf+dux0
> まぁ何だ。
> 俺の過去の経歴に比べたら、割れ厨なんて鼻くそレベルなんだけどなw
> 100人規模の集団サイバーテロの主犯とか、いろいろとな。


----------------------------------------------
この自動焼人 ★メールマガジンの配信停止をご希望される方は
http://qb5.2ch.net/test/read.cgi/sec2chd/1250169591/
にて自動焼人 ★までご連絡ください
0185デフォルトの名無しさん2009/09/04(金) 17:57:25
テンプレートメタで仮想関数の有無を調べることは
できないでしょうか?
今の知識では思い浮かばない・・
0186デフォルトの名無しさん2009/09/04(金) 18:47:50
その関数がPOD型かどうかを見るよろし
0187デフォルトの名無しさん2009/09/07(月) 01:32:34
関数がPODてなんじゃらほい。

クラスに仮想関数があるかどうかの話なら、boostのis_polymorphic
ですね。チェック対象クラスを継承した2つの同等なローカルクラスを
用意。但し片方はvirtualデストラクタ付きにしといて、2つの
sizeofの結果が同値なら元からvtbl付だった -> 仮想関数あった。
0188デフォルトの名無しさん2009/09/08(火) 11:57:34
なるほどー。質問者じゃないけど勉強になった
0189デフォルトの名無しさん2009/09/08(火) 13:20:46
MPLのスレとかあるのかなぁ、と思ってJaneのスレタイ検索窓に"MPL"と入れたら
ここが候補に挙がって、一瞬ものすごいインテリジェントな検索機能に見えた
0190デフォルトの名無しさん2009/09/08(火) 13:31:51
なるほど、teMPLateなのか。
0191デフォルトの名無しさん2009/09/09(水) 13:08:44
>>165

Modern C++ Design の正誤表はこちらに移動していました。
http://web.me.com/masaaki.murakami/sites/ModernC++Design/
0192デフォルトの名無しさん2009/09/10(木) 21:26:18
なんでも出来るなC++
0193デフォルトの名無しさん2009/09/17(木) 13:05:39
クラスに対してユニークなコンパイル時定数を割り振る方法ってある?
0194デフォルトの名無しさん2009/09/17(木) 13:17:57
MPLでそんなことができたかも知れない
0195デフォルトの名無しさん2009/09/17(木) 13:27:39
typeid(T) じゃだめ?
0196デフォルトの名無しさん2009/09/17(木) 13:30:55
数年前typeof作れないかとそれやろうとしてたけど無理っぽかった。
0197デフォルトの名無しさん2009/09/17(木) 14:43:18
C++0xでそんなことができたかも知れない
0198デフォルトの名無しさん2009/09/17(木) 14:56:10
確率計算の為のクラスを造るとします
内部でリストを持ち
要素の連綿の登録後
この要素は何個あるとか確率はなんぼとか返せるように造ると

しかし要素がペアだった時は同時確率を求められるようにしたいとします
その為に内部ではリストでなくマップで持つとします
k->v
これで(3,6)は何個とか瞬時に返せます

ここで困ったのです
ペアのペアで要素登録すると
(k1->v1)->(k2->v2)で管理するのでなく
k1->k2->k3->vとして欲しいのです
(1,8,4,3)は何個とか瞬時に返して欲しい

TMPなら解決できますか?
必要な深度のメタマップクラスを造ってくれるんです
0199デフォルトの名無しさん2009/09/17(木) 15:00:05
どっちかというと要素を専用のクラスにして、そのクラスのリストを持つべきなんじゃ?
0200デフォルトの名無しさん2009/09/18(金) 08:17:15
>>193
staticメンバのアドレスを取るとか…
0201デフォルトの名無しさん2009/09/18(金) 08:17:56
ああ、コンパイルタイム定数じゃないから駄目だな
0202992009/09/19(土) 21:39:29
>193
懐しい話題だな。
分割コンパイルが可能なうちは不可能だと思う。リンカと連動できれば違うんだろうけど。
実行時で良ければ>99だな。最近のコンパイラだったらそこそこ最適化できるんじゃない?

応用例をboost vaultに突っ込んでみたけど、誰も興味なさそうさんで絶賛放置中
ttp://www.boostpro.com/vault/index.php?action=downloadfile&filename=holder.zip&directory=Data%20Structures&
0203デフォルトの名無しさん2009/09/19(土) 23:32:48
久しぶりにプログラム板見たら、こんなスレが出来ていたので少しびっくり、
map のハッシュ値からキー値を検索するようなアルゴリズムって無いのでしょうか?
pair でmap へinsert した値を相互(キー値、ハッシュ値)で検索し合えれば
少し幸せになれるかと思いました、質問させてください、よろしく。
0204デフォルトの名無しさん2009/09/19(土) 23:36:31
>>203 boost::multi_index
0205デフォルトの名無しさん2009/09/19(土) 23:58:20
>>204 Thxです
流石boost いろいろそろってますね。
0206デフォルトの名無しさん2009/09/20(日) 01:25:15
static const char* foo = "FOO";
これを
static char* foo = "FOO";
このような型に変換したいのですが
template を用いてconst 剥がしが出来ないでしょうか?
0207デフォルトの名無しさん2009/09/20(日) 01:27:50
>>206
すでに変換できてるように見えるんだが、何がしたいんだって?
0208デフォルトの名無しさん2009/09/20(日) 01:50:50
>>206です
配列foo を、こんな感じで、使いたいんだけど、const が付いてると
first = foo;
ここで引っ掛かってコンパイルが通らないので、一時的にconst 剥がしが出来ないものかと、子一時間です。

template<class Iterator, class T>
Iterator search(T target)
{
static const char* foo = "FOO";
T* top;
T* first;
first = foo;
top = first;
〜省略〜
}
0209デフォルトの名無しさん2009/09/20(日) 01:58:57
>>208
const_cast でコンパイルは通せるけど、書き込んじゃダメなのは変わらないんだから、
first に const 付ければいいんじゃないの?
0210デフォルトの名無しさん2009/09/20(日) 02:11:35
>>208 です
>>209
なるほど
const T* top;
const T* first;
これで、いけました、処でまだconst 剥がしに拘るんだけど
template <class T>
struct remove_const {
typedef T type;
};

template <class T>
struct remove_const<const T> {
typedef T type;
};
こんなtemplate があったとしも、これでは
static const char* foo = "FOO";
この、const 剥がせません無いのですが、いい方法が無いんでしょうか?
0211デフォルトの名無しさん2009/09/20(日) 02:21:41
それはconst_castの仕事でござるよ
0212デフォルトの名無しさん2009/09/20(日) 08:54:19
>>211
だがしかし、それは悪い方法である。

剥がさないのがいい方法ね。 >>210
0213デフォルトの名無しさん2009/09/20(日) 09:57:31
const剥がしの目的にもよるが、面倒とかよく分からないとかいう理由で剥がすのは
危険だからちゃんと慣れるべき。Cでポインタ分からないままコーディングするのに
近いレベル。
constを剥がす正当な理由は、「const非対応な古いコードor糞コードと組み合わせ
なきゃならない時に仕方なく」というもの。それはconst_castでやる。
const剥がしのキャストは一見大したこと無いけど、見た目よりは危険だから避ける
べき。
0214デフォルトの名無しさん2009/09/20(日) 13:15:10
メタ関数で階乗などの整数値を計算できるのは理解したんですが
円周率などの実数値を計算することはできないんでしょうか?
0215デフォルトの名無しさん2009/09/20(日) 13:22:41
浮動小数の仕組みを思い出そう。
0216デフォルトの名無しさん2009/09/20(日) 13:47:51
実数のような無限列はそもそもコンピュータでは扱えない。
浮動小数に近似するとしても、どこまで近似するかという問題があるから簡単には扱えんよ。
0217デフォルトの名無しさん2009/09/20(日) 17:09:41
逆に、どこまで近似するか決めれば扱えるんじゃね?
0218デフォルトの名無しさん2009/09/20(日) 17:11:52
MPLで浮動小数使いたければfloatやdoubleをコンピュータが内部でやってるのと同じ事をMPLですればいい。
ただものすごく面倒臭いし遅い。
0xではコンパイルタイムにfloatとdouble使えるけどね^ε^
0219デフォルトの名無しさん2009/09/20(日) 17:17:11
どこまで近似するか決めないと浮動小数演算そのものが無理だしな
コンパイルが糞遅いのは、プリコンパイルヘッダが優秀なコンパイラならマシになる
かもしれない

でもまぁ現実的に考えればC++0x待ち
0220デフォルトの名無しさん2009/09/20(日) 18:07:14
現行では整数の対で有理数を作って近似するしか無いね。
constexprの実装まだー。
0221デフォルトの名無しさん2009/10/02(金) 17:47:34
あるクラスが
・メンバ変数Xをもっているか否か
・メンバ関数Yをもっているか否か
を調べる方法はありますん?
typedef Zを持っているかどうかはわかったんですが・・・
0222デフォルトの名無しさん2009/10/02(金) 17:58:25
ちなみにやりたいことは
operator []を持ってれば
template <class T>
void f(const T &val)
{
cout << val[0];
}

operator []を持ってなくてfirstを持ってれば
template <class T>
void f(const T &val)
{
cout << val.first;
}

それ以外はコンパイルエラー

といった感じで分岐させたいです
0223デフォルトの名無しさん2009/10/02(金) 18:25:38
BOOST_MPL_HAS_XXX_TRAIT_DEFを使うとか?
0224デフォルトの名無しさん2009/10/04(日) 09:07:43
>221
移植性のある方法では現行 C++ では出来ないと思う。
VC だと __if_exists があるし、処理系によっては SFINAE の適用範囲が広くて使えるかもしれない。
無理して頑張ったところでどうせ意味論までは確認できないんだから、素直に traits クラス作っちゃった方がいいんじゃないかな。
0225デフォルトの名無しさん2009/10/04(日) 16:21:57
Boostライブラリはたまに移植性のない方法を無理矢理カバーしてるからなぁ
あとC++0xなら普通に作るはず
0226デフォルトの名無しさん2009/10/12(月) 16:26:18
TMPを発見するような事を真にハックするって言うんだよな
0227デフォルトの名無しさん2009/10/17(土) 13:31:04
コンパイル時に文字列って操作できる?
staticな配列が無いからタイプリストにchar2typeを詰め込んで・・・とか思ったけどすごいめんどくさそうだ
0228デフォルトの名無しさん2009/10/17(土) 13:33:06
>>227 boost::mpl::string で?
0229デフォルトの名無しさん2009/10/17(土) 13:37:29
もっと具体的にどういう操作がしたいんだ
0230デフォルトの名無しさん2009/10/17(土) 14:00:30
文字列の基本的な操作ができないものかなと
cpy,cat,cmp・・・などができて、実行時にはゼロ終端かstd::stringで取り出せる
みたいな感じで
0231デフォルトの名無しさん2009/10/17(土) 14:06:55
まぁ何だ、プリプロセッサも立派なメタプログラミングだぜ!
0232デフォルトの名無しさん2009/10/17(土) 15:49:24
機能的制約はあっても制約を記述できない「ベーシックですか?」的なメタだけどな
0233デフォルトの名無しさん2009/10/17(土) 18:17:29
>230
>228 の言うとおり boost::mpl::string でできるだろう。

ドキュメントのサンプルより:
>typedef mpl::string<'hell','o wo','rld'> hello;
>typedef mpl::push_back<hello, mpl::char_<'!'> >::type hello2;
>
>BOOST_ASSERT(0 == std::strcmp(mpl::c_str<hello2>::value, "hello world!"));
0234デフォルトの名無しさん2009/10/17(土) 18:58:20
それ4文字以下のセットじゃないと使えないししかも環境依存しまくりじゃなかったっけ?
0235デフォルトの名無しさん2009/10/17(土) 21:13:26
>234
multicharacter literal についてならその通り。4文字以下ってのも実装依存っぽいけど。
その辺は吸収するつもりなんだろ、きっと。primary test compilers だと test は全部通ってるみたい。
後、嫌だったら別に一文字づつ書いても構わないみたいだ。
0236デフォルトの名無しさん2009/11/09(月) 12:25:10
TMPを理解するのに必要なIQはいくつですか?
126しか無いんですが、難しいですか?
0237デフォルトの名無しさん2009/11/09(月) 12:35:12
しらねーけど子供の頃130だった俺は楽勝だから126でも大差ねーだろ
0238デフォルトの名無しさん2009/11/09(月) 12:36:16
>>236
IQとTMPの理解にリニアな相関性はありません。
IQが多少低くてもセンスがあれば理解できるでしょう。
0239デフォルトの名無しさん2009/11/09(月) 17:37:20
TMPが難しいのは修得人口が少ない(よって解説も少ない)のと
C++のテンプレートが元々TMP用のものではないことによる不合理性が原因。
別に理論として難しいわけじゃない。
0240デフォルトの名無しさん2009/11/09(月) 18:12:34
メタしないC++になんの価値が有るの
いまどき
0241デフォルトの名無しさん2009/11/09(月) 18:20:36
なんだと
メタメタにしてやろうか小僧
0242デフォルトの名無しさん2009/11/10(火) 05:49:32
C/C++のエラーチェックにこれまでGNU nanaを使ってきました。
boostにそういうものってありますか?
>>233にある

BOOST_ASSERT

あたりがそれですか?
0243デフォルトの名無しさん2009/11/10(火) 20:49:10
継承してる一番遠いサブクラスのサイズをコンパイル時に取得できる?
0244デフォルトの名無しさん2009/11/10(火) 20:53:17
オンナスキーっていうレズキャラだせばよかったのに
0245デフォルトの名無しさん2009/11/20(金) 11:26:19
template <class Gadget> class Widget
{
public:
    Widget(???) : m_gadget(???) {}

private:
    Gadget m_gadget;
};

m_gadgetをデフォルト以外で初期化したい、初期化パラメータはクライアントが選べるようにしたい
でもWidgetはGadgetのことをよく知らないのでコンストラクタにどんな引数を持つべきかわからない
これを解決したいんですが、Widgetの???をテンプレートパラメータから決定することはできますか?
0246デフォルトの名無しさん2009/11/20(金) 11:37:48
c++0x なら
Gadgetのコンストラクタ引数を可変引数 template にして:

template <class Gadget, typename... Args>
class Widget {
public:
  Widget(Args... args): m_gadget(args...) {}

private:
  Gadget m_gadget;
};
0247デフォルトの名無しさん2009/11/20(金) 11:41:46
template <class Gadget>
class Widget {
public:
  template <typename... Args>
  Widget(Args... args): m_gadget(args...) {}

private:
  Gadget m_gadget;
};

の方がいいか。
0248デフォルトの名無しさん2009/11/21(土) 01:29:04
どうせなら perfect forwarding にしたいかもね。
別解として Boost In Place Factory とか。
0249デフォルトの名無しさん2009/11/21(土) 17:54:20
ポリシーとトレイツのしっかりとした定義がわからない

template <class T> class X : public T
{
using T::func;
using T::num; int a[num];
};

↑こういうのってtraitsなの?policyなの?
0250デフォルトの名無しさん2009/12/02(水) 00:31:19
enable_ifか何かで定数の比較( > とか <= )で
templateの特殊化分岐ってできましたっけ?
0251デフォルトの名無しさん2009/12/02(水) 00:44:28
enable_if_cだった
0252デフォルトの名無しさん2009/12/02(水) 15:34:58
そりゃできるだろ
0253250-2512009/12/02(水) 17:39:30
眠かったので分けの分からん文章書いてしまいましたが、
250書いたすぐ後にenable_if_cで定数比較ができるのが分かりました。
<enable_if使ってできねーできねー言って悩んでたまぬけ
0254デフォルトの名無しさん2009/12/02(水) 18:20:37
enable_ifでもMPLのint_とか適当に使えば行けるとは思うが、まぁenable_if_cで
済んでるのを無駄にややこしくする必要は無いな
0255デフォルトの名無しさん2009/12/13(日) 11:27:26
struct Foo {
template <typename F> Foo(F f)
{
typedef typename boost::mpl::if_c<boost::is_pointer<F>::value, function_ptr_tag, function_obj_tag>::type tag;
// do something
}
}
みたいに関数へのポインタか関数オブジェクトを渡す際、
関数オブジェクトのコピーを抑制するにはどうすれば良いんでしょうか? boost::ref 以外で。
関数オブジェクトの所有権を Foo 側で持ちたいので、最低 1 回のコピーだけで済ませたいのですが。
一応、試しに Foo (const F& f) としてみたら期待通りに動いたんですが、
boost::function とかはそういう実装になってないから、何か問題があるんだと思ったのですが。
0256デフォルトの名無しさん2010/01/13(水) 10:59:25
ひょっとして今のテンプレメタってC++0x普及したらいらない子状態になるんですか?
0257デフォルトの名無しさん2010/01/13(水) 14:07:48
なるわけがない
0258デフォルトの名無しさん2010/01/13(水) 21:44:04
幾つかのテクニックはいらない子になるだろ
0259デフォルトの名無しさん2010/01/13(水) 23:46:41
それは今のテンプレートメタが要らない子になるとは言わない
0260デフォルトの名無しさん2010/01/22(金) 18:51:33
>>99
やっぱこれすごいわ
よく思いつくなぁ
0261デフォルトの名無しさん2010/01/22(金) 19:33:45
俺はLokiのInt2Typeを見て感動したなぁ。
整数定数を与えると、値ごとに異なる型を返すテンプレート。
99と逆な感じかな。
0262デフォルトの名無しさん2010/01/22(金) 23:23:14
>>99はコード上ではすっきりしてるけど、コンパイルすると普通に条件分岐やフラグ
を含んだコードを生成するよね
別にそれが悪いって訳ではないんだが
0263デフォルトの名無しさん2010/01/23(土) 00:16:20
まあ、条件分岐やフラグをコンパイラに押し付けているのがポイントかね。
遠い将来にC++が自己書き換えプログラムを作るようになったら効率化するかもね。

誰か>202のマルチスレッドにコメントしてくれないかしらん。
boost::anyで標準対応してくれないかなぁ……
0264デフォルトの名無しさん2010/01/23(土) 01:10:26
>>99ってひとつのEXEであれば型の数が確定してると思うけど
最新のVCあたりなら最適化で定数になったりしないの?
0265デフォルトの名無しさん2010/01/23(土) 04:48:19
呼び出される順序で値がかわってくるので完全にconstな関数やインスタンスからしか呼び出されてない場合でないと
定数に展開されない。
0266デフォルトの名無しさん2010/01/23(土) 06:29:14
typeidのアドレスでも使えばいいんじゃないの?
0267デフォルトの名無しさん2010/01/23(土) 12:42:12
というか正直>>99は使えそうで使えない罠コードにしか見えなくね
0268デフォルトの名無しさん2010/01/23(土) 13:22:41
まあ、>99だと普通にマルチスレッドとか鬼門だと思う。

>266
type_infoに一意性てあったっけ?比較はOKだけど。

0269デフォルトの名無しさん2010/02/13(土) 03:10:05
テンプレートのインスタンス化の度にインクリメントされる様な定数は無理ってこと?
0270デフォルトの名無しさん2010/02/13(土) 04:08:21
静的な定数に最適化はされないんじゃね
0271デフォルトの名無しさん2010/02/13(土) 04:09:30
静的じゃなくてコンパイル時定数と言いたかった
0272デフォルトの名無しさん2010/02/27(土) 02:41:28
struct A { B operator (C); D operator (E); };

AとCorEをテンプレートパラメータにしてBorDを得るイディオムって有りますか?
0273デフォルトの名無しさん2010/02/27(土) 03:24:57
C++0xなら decltype((*(A*)nullptr)(*(C*)nullptr))
Aがboostかtr1のresult_ofに対応していれば typename result_of<A(C)>::type
どっちも駄目なら諦める
0274デフォルトの名無しさん2010/04/10(土) 13:56:10
なんか3月にTMPの書籍出てたみたいだけど
どう?買い?
0275デフォルトの名無しさん2010/04/10(土) 17:35:28
どれよ
0276デフォルトの名無しさん2010/04/10(土) 22:47:59
>>275
ISBN-10: 4798120391
(ISBN-13: 978-4798120393)
です
0277デフォルトの名無しさん2010/04/11(日) 21:04:43
>>274
http://vig.pearsoned.com/store/product/1,1207,store-15080_isbn-0321227255,00.html
これの翻訳なんで、まだ読んでなければ必読でしょ。

http://www.vandevoorde.com/C++Templates/
これの翻訳も出たよね。

どっちも訳がいいかどうかは知らないけど、
template好きは、訳が悪くても読まないとね。
0278デフォルトの名無しさん2010/04/11(日) 21:07:01
template好きはたぶん原書で読んでる
ちょっと好きなだけの俺は邦訳を買ってみよう
0279デフォルトの名無しさん2010/04/17(土) 15:25:59
原著たかくね?
0280デフォルトの名無しさん2010/04/17(土) 15:51:30
内容考えれば安い。
これだけ高度な内容の方が出ている言語は珍しい。
0281デフォルトの名無しさん2010/04/17(土) 21:56:32
隠し芸と言うか裏芸というか、こういう技覚えて皆実践してんの?
0282デフォルトの名無しさん2010/04/19(月) 12:10:26
type erasureが必要だったから覚えた
この程度に使うだけならそれほど難しいものでもないし
0283デフォルトの名無しさん2010/05/29(土) 08:30:45
メンバでない関数
namespace x
{
r f(a1, a2, ...);
}
が存在するかどうか調べることってできる?
リンクできるかどうかは流石に無理だろうから、宣言できるかどうかだけでも調べたい
0284デフォルトの名無しさん2010/05/30(日) 15:05:19
>283
どこまで厳密に調べたいかによるけどものすごく適当にやるとこんな感じ?
ttp://codepad.org/aNznrWhl
0285デフォルトの名無しさん2010/06/01(火) 22:24:28
int i;
hoge h;
fuga f;
piyo p;
for_each(i, h, f, p).do(print);

とか

int i, j;
hoge *p, *q;
for_each_pair({i, j}, {p, q}).do(swap);

みたいな書き方を実現するテンプラテクニックってありますか?
c++0xのみ可でもおkです
0286デフォルトの名無しさん2010/06/01(火) 23:17:24
みたいなと言われてもその表記の意味する所がわからんのだが
0287デフォルトの名無しさん2010/06/02(水) 05:44:28
>>285
異なる型からなるシーケンスにSTLライクにアルゴリズムを適用したいってこと?
後者は知らんが前者は
fusion::for_each(fusion::vector_tie(i, h, f, p), print);
とほぼ同意だからboost::fusionでも参考にすりゃ出来るんじゃないの
0288デフォルトの名無しさん2010/06/02(水) 07:38:19
後者はそもそもi, i, p, qがboost::bariantoじゃないと無理だな
0289デフォルトの名無しさん2010/06/02(水) 07:39:01
bariantoじゃなくてani-な
0290デフォルトの名無しさん2010/06/02(水) 07:40:10
>>287
thxです!
0291デフォルトの名無しさん2010/06/04(金) 04:50:47
ruby厨か・・・
0292デフォルトの名無しさん2010/06/05(土) 10:20:02
ttp://codepad.org/VlTTMgbi

たかがアドレスひとつ取るのにこの人はなんでこんなに頑張ってるんですか?
いったいこのコードにはどんな意味があるんでしょうか?
0293デフォルトの名無しさん2010/06/05(土) 10:26:55
operator& がユーザーにオーバーロードされてても
アドレスを取得できるようにするため
0294デフォルトの名無しさん2010/06/05(土) 10:31:56
なるほど!
0295デフォルトの名無しさん2010/06/05(土) 18:00:02
もちろん、原理を理解したら、普段はboost::adress_ofを使えばいい。
0296デフォルトの名無しさん2010/06/05(土) 18:01:04
すまん、addressofだった
0297デフォルトの名無しさん2010/06/05(土) 18:06:54
普通にアドレスとって欲しくないから&とかオーバーロードするのにキモイキャストまでしてアドレスとるなよって思う
0298デフォルトの名無しさん2010/06/05(土) 20:26:47
COMやってたら CAdapt が必要になるようなケースで
それが必要なくなるということか
どっちもどっちな気もするが
0299デフォルトの名無しさん2010/06/05(土) 21:15:39
ライブラリをジェネリックにしようとすれば
普段はしないような細かい配慮が必要になるってこった。
0300デフォルトの名無しさん2010/06/05(土) 22:21:56
善し悪しはべつにしてなんでvolatileと引数のint longがなんのために存在するのかわからん
0301デフォルトの名無しさん2010/06/07(月) 05:16:51
>>292
のコードで、なんでaddr_impl_refが必要なのかわからない
誰かおせーて
0302デフォルトの名無しさん2010/07/29(木) 21:29:16
自然数の定数nを与えると、n≦m = 1<<x (n以上かつ最小の2のべき乗の値)を求めるテンプレートを組みたいのですが、
どのように組めばよいでしょうか?
例えば以下のコードのような感じで、n=33と与えると64を定数として求めたいのです
size_t m = 1;
while (m < n) m <<= 1; //事前展開してくれない
0303デフォルトの名無しさん2010/07/29(木) 21:47:04
そういうのを見るとつい2の補数のアーキテクチャの時の面白ビット演算をやりたくなるが、
仮にアーキ依存していいとしたらテンプレートでああいうのって可能なんかな
まぁどうでもいいが
0304デフォルトの名無しさん2010/07/30(金) 00:29:00
>>302
かなり適当
http://codepad.org/6fNNGemT
0305デフォルトの名無しさん2010/07/30(金) 21:29:20
>>304
ありがとうございます
再帰で書き直して置き換える感じなのだと理解しました
size_t binarywrap(size_t n, size_t m = 0) { return m < n ? binarywrap(n, m << 1) : m; }

boostが使えない環境なので以下のようにして使わせていただいてます
template <bool B, size_t T, size_t F> struct binarywrap_t { static const size_t size = T; };
template <size_t T, size_t F> struct binarywrap_t<false, T, F> { static const size_t size = F; };
template <size_t n, size_t m = 1> struct binarywrap {
static const size_t size = binarywrap_t<(m < n), binarywrap<n, (m << 1)>::size, m>::size;
};
template <size_t n> struct binarywrap<n, 0> { static const size_t size = 0; }; // これを省略するとなぜかエラーが出る…なぜだ…
0306デフォルトの名無しさん2010/09/16(木) 12:32:46
基底クラスの数や型を得るメタ関ってできる?
0307デフォルトの名無しさん2010/09/17(金) 16:17:25
>>306
こういうのだろうか
ttp://www.kmonos.net/alang/boost/classes/call_traits.html
ttp://www.kmonos.net/alang/boost/classes/type_traits.html
0308デフォルトの名無しさん2010/10/15(金) 23:05:36
こんなのを作ってみた。マクロ以外の呼び出せるもの
全部同じオブジェクトで呼び出せるクラス。
これもメタプログラミングなのかな?

Delegate<Child*(int,int,int)> method[]=
{
 &functor,  //Child *operator(int,int,int);を定義しているオブジェクト
 &function, //Child *function(int,int,int); 普通の関数
 Type(),  //new Child(int,int,int);コンストラクター Typeは空のクラス
 Delegate<Child(int,int,int)>(&object,&Class::Method) //オブジェクトと関数のペア
};
Delegate<Parent*(int,int,int)> parent_method=method[0]; //変換可能ならキャストできる
使い道としては関数ポインタの代わりとかイベントの伝達につかってるよ。
for(int i=0;i<n;++i)method[i](a,b,c);
0309デフォルトの名無しさん2010/10/16(土) 01:14:25
>>308 boost::function に比べてなんかいいことある?
0310デフォルトの名無しさん2010/10/16(土) 15:17:40
>>309
functionつかった事ないから知らんけど、
bindがあっても無くてもいい所と、コンストラクターになれる所くらい?
あとは、コードサイズが違うかもしれん。
0311デフォルトの名無しさん2010/10/30(土) 10:36:41
>>310
それらはfunctionでもできるね。
>>309
プログラム技術習得として、function相当の機能を作った経験はあったほうがいいと思うぞ。
0312デフォルトの名無しさん2010/11/29(月) 19:12:12
/** 移植性のないユニークな識別子
* 関数定義が増えたり#includeが増えたりすると値が変わる(セクション内の定義位置が変わるので)
*/
//@{
template<class T>
inline unsigned UniqueID() { return reinterpret_cast<unsigned>(UniqueID<T>); }
template<class T>
inline unsigned UniqueID(const T&) { return UniqueID<T>(); }
//@}

template<class T, class U>
inline bool InstanceOf(const U&) { return UniqueID<T>() == UniqueID<U>(); }
template<class T, class U>
inline bool InstanceOf(const T&, const U&) { return InstanceOf<T>( *reinterpret_cast<U*>(0) ); }

template<class T, class U>
inline bool StrictInstanceOf() {
 static_cast<T*>( reinterpret_cast<U*>(0) );
 static_cast<U*>( reinterpret_cast<T*>(0) );
 return true; // 相互に型変換が不可能ならここでコンパイルエラーで止まる
}
template<class T, class U>
inline bool StrictInstanceOf(const U&) {
 return StrictInstanceOf<T, U>();
}
template<class T, class U>
inline bool StrictInstanceOf(const T&, const U&) {
 return StrictInstanceOf<T, U>();
}
0313デフォルトの名無しさん2010/11/29(月) 20:22:18
メンバ関数ポインタを汎用的に格納するにはどうしたらいいんだ
void*じゃダメなのはわかるんだけど
0314デフォルトの名無しさん2010/11/29(月) 22:23:11
Boost.Anyのソースを読むといい。
0315デフォルトの名無しさん2010/11/29(月) 23:12:18
>>313
遅延実行が目的ならstd::function、std::bindが一番頭使わない方法かな
stdになければtr1かboost
あるいは>>308のようにtype erasureやcompositionの技法で
自分で書くこともできるけど、スマポも格納したいとか、safe boolを
実装したいとか、いろいろ考え出すと結構面倒
0316デフォルトの名無しさん2011/02/20(日) 10:54:54.24
このスレちっとも進まないですよね
所詮ねらー風情にはオーバーテクノロジーなんでしょうね
0317デフォルトの名無しさん2011/02/20(日) 11:42:38.46
テンプレートより自家プリプロセッサの方がよくね
0318デフォルトの名無しさん2011/02/20(日) 12:41:31.36
C++0xが普通に使えるようになったらメタ関数をいちいち typename HOGE<HUGA>::type
ってしなくても HOGE<HUGA> で済むようになるから使用頻度は増えると思う。
現行のメタ関数はlazyな解決に使う方向だな。

template<typename MetaFunc> using Eval = typename MetaFunc::type;
template<typename T> struct LazyIdentity { using type = T; };
template<typename T> using Identity = Eval<LazyIdentity<T>>;
0319デフォルトの名無しさん2011/04/27(水) 11:52:39.52
このスレちっとも進まないですよね
所詮ねらー風情にはオーバーテクノロジーなんでしょうね
0320デフォルトの名無しさん2011/04/27(水) 12:03:45.76
C++相談室で十分だから。
0321デフォルトの名無しさん2011/04/30(土) 13:18:16.10
ぶっちゃけこの辺の技術を使うには、ぐぐって自力でどうにかする能力が必須
0322デフォルトの名無しさん2011/04/30(土) 16:15:52.69
ちょっとTMP使うだけでも阿呆のようにコンパイル時間とオブジェクトサイズが増えるのは
早めに何とかしてもらいたいものだ。
コンパイラの人が頑張ればどうにかなるのかはわからないが。
0323デフォルトの名無しさん2011/05/03(火) 11:23:14.13
スクリプトでヘッダとソース生成したほうが簡単柔軟コスト安だよねJK
0324デフォルトの名無しさん2011/05/03(火) 12:50:51.93
>>323
まとめて修正したくなると面倒に・・・
0325デフォルトの名無しさん2011/05/03(火) 18:28:50.62
そもそもその手法にはプリプロセッサマクロと同様の問題がある
0326デフォルトの名無しさん2011/05/03(火) 18:34:49.20
いやぁ、どう考えてもLisp辺りで生成した方が柔軟で面倒が無いわ
0327デフォルトの名無しさん2011/05/03(火) 18:55:31.63
どの辺に時間がかかっているんだろう
0328デフォルトの名無しさん2011/05/03(火) 23:16:20.69
forthみたいなimmediateワード欲しいね。
0329デフォルトの名無しさん2011/05/03(火) 23:31:00.92
>>327
素人考えだと組み合わせの生成と検索じゃね
0330デフォルトの名無しさん2011/05/03(火) 23:34:53.91
TMPやってる人ってコンパイル時にかかるコスト計算とかもしてるの?
これは展開にO(n^2)かかる〜とかこの処理はオーバーヘッドが大きい〜とか
0331デフォルトの名無しさん2011/05/04(水) 02:35:23.67
時間がかかる程高度なことやってる気になる
0332デフォルトの名無しさん2011/05/04(水) 14:06:48.82
>>330
Boost.MPL のアルゴリズムにも計算量が定義されていたりする。
0333デフォルトの名無しさん2011/05/04(水) 14:40:18.86
テンプレートでプログラムを表現するコードを書いてみた。
http://codepad.org/Ol10cCgK
実行時にできる事をテンプレートで作成してもなんの意味も無いけど、
テンプレートプログラムを元にクラスを生成するならオートマトン(構文解析器等)
作成なんかで便利そうな気がする。
0334デフォルトの名無しさん2011/05/06(金) 01:42:38.93
オートマトンでは構文解析はできんぞい
0335デフォルトの名無しさん2011/05/06(金) 02:11:56.61
いや、できるな。ごめん字句解析の限界とスタックをオートマトンで構文解析する方法を混同してた。
0336デフォルトの名無しさん2011/05/06(金) 19:29:58.22
もしかしたら拡張するかもなクラスに
余分に使わないテンプレート引数を設定するのって普通?
0337デフォルトの名無しさん2011/05/06(金) 22:56:44.80
デフォルト引数ってそもそも、引数の変更が有っても
MethodExExExみたいなのを書かないようにする仕組みじゃないのか?
0338デフォルトの名無しさん2011/05/07(土) 00:49:16.57
>>336
後から追加できるのに、わざわざ先手打つ必要ないでしょ。
組み合わせ爆発起きそうなテンプレート群でもない限り。
0339デフォルトの名無しさん2011/05/07(土) 01:35:08.02
>336
拡張した後に特殊化で互換性取った方が良くない?
0340デフォルトの名無しさん2011/05/08(日) 23:27:38.49
クラス定義中に自分自身のサイズを知る方法はある?

template <〜> class hoge
{
typedef hoge this_type;
static unsigned int const this_type_size = ???; // this_typeのサイズを知りたい
};
0341デフォルトの名無しさん2011/05/08(日) 23:29:57.04
template<〜> class hoge{
 enum{ size = sizeof(hoge) };
}

hogeを直接クラス内で書けばテンプレート引数は省略できる。よってthis_typeは必要ない。
staticおよびconst修飾ではなくenumでとるべき。
0342デフォルトの名無しさん2011/05/08(日) 23:42:58.58
>>341
enumを使う必要はない。
今時C++03未対応のコンパイラーなんて、
そもそもテンプレート自体ろくに扱えないだろうし。
0343デフォルトの名無しさん2011/05/09(月) 00:02:27.71
>>340ではないけど。

エラーになったんだけど書き方間違ってる?
ttp://codepad.org/QaDd7R2K
0344デフォルトの名無しさん2011/05/09(月) 05:39:16.38
>>342
VC9.0「はい。」
0345デフォルトの名無しさん2011/05/09(月) 09:28:32.30
class c{
int a[sizeof (c)+1];
};
サイズ取れたらどうなるの?
0346デフォルトの名無しさん2011/05/09(月) 10:06:10.09
クラスはクラス定義の終了以後に定義されるので、
クラス定義内では、クラス名は不完全型として扱われる。
sizeofのオペランドに不完全型を渡すと鼻から悪魔。
そのため、>>341,354のようなコードは不可。

クラス定義内のメンバー関数定義における仮引数と戻り値の型は、
クラス名を使ってもいいとされている。
そうしないと、クラス定義内で自分のクラス型を使うメンバー関数を定義できないから。
0347デフォルトの名無しさん2011/05/09(月) 10:51:44.39
>>346
> sizeofのオペランドに不完全型を渡すと鼻から悪魔。
コンパイルエラーになるだけだよ。
0348デフォルトの名無しさん2011/05/09(月) 11:12:45.24
C++ではそうだけど、sizeofに不完全型を渡すってのが鼻から悪魔の元ネタだからつい。
0349デフォルトの名無しさん2011/05/09(月) 11:26:33.85
>>348
C++のほかにsizeofっていうとCぐらいしか思いつかないんだけど、
Cでも同じでコンパイルエラーになるだけだよ。
元ネタとか、何の話してんの?
0350デフォルトの名無しさん2011/05/09(月) 12:24:44.03
元ネタ?
ttp://groups.google.com/group/comp.std.c/msg/dfe1ef367547684b
上記を元ネタとして言及
ttp://cpplover.blogspot.com/2010/01/c0x_14.html

ただ元ネタ?で引用してる規格でも
> 3.3.3.4 The sizeof Operator
> Constraints
> The sizeof operator shall not be applied to an expression that has function type or an incomplete type,(以下略)
不完全型に適用すべきでないとなっているだけだから
不適切なsizeofを未定義動作になると解釈して鼻から悪魔が出ても文句は言えないと例えたのは元ネタ?を書いた人の誤解のように思える。
(今の感覚では未定義動作になると明言していない以上そもそもコードとして実行しない=その時点でコンパイルエラーにする、と読むほうが自然だと思う)
0351デフォルトの名無しさん2011/05/09(月) 12:37:39.53
「すべきでない」だとほとんど誤訳、誤読に近いね。
(適用する余地が少しはあるように読める)
規約の"shall not"は「してはならない」と訳す。
"shall"は「しなければならない。」
この辺の用語、訳は法令に準じてる。
原文でももちろん同じ。

上のURLの記事はどちらも酷いなw
0352デフォルトの名無しさん2011/05/09(月) 20:18:27.64
>>343
http://codepad.org/D5hRwEPj
0353デフォルトの名無しさん2011/05/09(月) 20:39:26.68
>>350-351
いやshall notに違反したらundefined behaviorだってちゃんと書いてあるだろ
0354デフォルトの名無しさん2011/05/09(月) 22:47:27.65
>>352
あれ?クラス宣言内でデフォルトの引数書けたっけ??
GCC拡張だったような記憶ががががが。。。orz
0355デフォルトの名無しさん2011/05/09(月) 23:58:28.52
>>353
よくわからん。
> If a "shall" or "shall not" requirement that appears outside of a constraint is violated, the behavior is undefined.
というのはみつけたがsizeofの説明はconstraintsなんだから上記には該当しないで
> "shall not" is to be interpreted as a prohibition.
こっちじゃないか?それとも別の記述?
0356デフォルトの名無しさん2011/05/10(火) 00:16:57.23
>>355
ここ。
5.1.1.3 Diagnostics
> A conforming implementation shall produce at least one diagnostic message (...) if
> ... or translation unit contains a violation of any syntax rule or constraint, ...
0357デフォルトの名無しさん2011/05/10(火) 01:28:56.98
>>356
それは診断メッセージの話であって一連の流れとは無関係に思えるけど。
未定義動作の一つとして診断メッセージを出してエラーにするというのはありでも
違反があったときに診断メッセージを出さなければいけないからその違反は未定義動作であるということにはならないでしょう。
03583562011/05/10(火) 02:04:23.78
>>357
ごめん。結論をちゃんと書いてなくて紛らわしかったね。
未定義動作にはならなくて、コンパイルエラーになるだけっていうほうの根拠を挙げたつもりだった。
0359デフォルトの名無しさん2011/05/10(火) 11:08:18.36
> constraint
> restriction, either syntactic or semantic, by which the exposition of language elements is to be interpreted
なのでconstraint違反は、interpretされない=コンパイルされない=コンパイルエラーを出して終了、だろう。
だからsizeofに不完全型を渡すは未定義動作じゃなくコンパイルエラーだな。
0360デフォルトの名無しさん2011/05/10(火) 11:12:14.81
そりゃそうだ。
最初から>>347>>349に書いてる奴がいる通りだ。
0361デフォルトの名無しさん2011/05/25(水) 16:23:06.59
TMPで整数型のビット幅を求める完璧な方法はある?
0362デフォルトの名無しさん2011/05/25(水) 17:17:24.99
sizeof(T)*CHAR_BIT こういう話??
0363デフォルトの名無しさん2011/05/25(水) 17:37:36.59
それは全然パーフェクトではないらしいです
0364デフォルトの名無しさん2011/05/25(水) 17:47:52.46
任意の整数値とは書いてないからねー。
0365デフォルトの名無しさん2011/05/25(水) 18:47:17.89
完璧かどうかはわからん
#include <iostream>
#include <limits>
#include <type_traits>

template<class T>
struct Bits {
enum { value = std::numeric_limits< typename std::make_unsigned<T>::type >::digits };
};

int main()
{
std::cout << Bits<int>::value << std::endl;
std::cout << Bits<short>::value << std::endl;
std::cout << Bits<char>::value << std::endl;
return 0;
}
0366デフォルトの名無しさん2011/05/25(水) 18:59:55.35
暇だから任意の数字のビット数出そうとおもったけど何かへんだ。
ttp://ideone.com/CwyGq
0367デフォルトの名無しさん2011/05/25(水) 23:19:50.83
template<class car,class cdr> struct Cell;
typedef Cell<class X,Nil> cell;

 Cellが本体未定義でも使用可能なのと同じで、
Xは未定義でも、template引数に直にclass Xと書いてやれば、
XをCellに渡せる訳だけど、このXどこか広域空間以外の名前空間に
所属させる事できないの?
Xの実体は不要で、templateを特殊化するための識別子としてだけ
使いたいんだけど、広域空間にあると他の名前との干渉が気になって
安易に使えない。
0368デフォルトの名無しさん2011/05/26(木) 00:00:29.35
>>367
namespace CellTags { class X; } とでもしておけばいいんじゃない?
0369デフォルトの名無しさん2011/05/26(木) 00:12:50.55
>>368

struct Example
{
        typedef Cell<class X,Cell<class Y,Nil>> cell;
};
っていうほんと使い捨てな用途に使えないよ。
こんな感じで書くのと変わんないし。
struct Example
{
        typedef Symbol<0> X;
        typedef Symbol<1> Y;
        typedef Cell<X,Cell<Y,Nil>> cell;
};
0370デフォルトの名無しさん2011/05/26(木) 00:47:20.69
>>369
ふーん。
長いサフィックスをつけるマクロでも作れば?
0371デフォルトの名無しさん2011/05/26(木) 00:51:48.23

なるほど。その手があるな。
もう少し代替手段を考えたいとこでもあるけど。
0372デフォルトの名無しさん2011/05/26(木) 01:04:00.31
>367
Cellを含めて適切なnamespaceに置いたら?
0373デフォルトの名無しさん2011/05/26(木) 01:19:44.58
>>372
実際には関数の中で使用するからどこの名前空間で使われるか解らん。
もっと現実に忠実に書くとこんな感じ。

Foo<Evalute< S< Setq,struct X,S<Quote,S<Lambda S<struct Args>, S<いろいろ処理> > > > > > processor(xxx,yyy,zzz);
0374デフォルトの名無しさん2011/05/26(木) 18:49:45.22
それで使い捨てなのか
0375デフォルトの名無しさん2011/05/26(木) 22:05:04.33
TMP
こだわりすぎて
損をする
人に任せて
成果だけ得る
0376デフォルトの名無しさん2011/05/26(木) 22:11:45.99
>>375
Tだすせ得
Tこ損人成

・・・どう読むんだ、
0377デフォルトの名無しさん2011/05/27(金) 00:52:11.46
>373
無茶言うな。
せいぜいCRTP使って唯一性を確認するのが関の山だろ。
とりあえずVC++2010で動いた。鼻から悪魔かもしれんが。
int unique() { static int i(0); return i++; };
template<typename car> struct Cell {
static int id() {
static int i(unique());
return i;
};
};
template<typename T> struct CellTagBase {
template<int i> struct id;
friend T;
};
class Tag : public CellTagBase<Tag> {};
class Tag2 : public CellTagBase<Tag2> {};
// class Tag2 : public CellTagBase<Tag2> {}; --> error
int main(int argc, _TCHAR* argv[])
{
std::cout << Cell<Tag::id<0> >::id() << std::endl;
std::cout << Cell<Tag2::id<1> >::id() << std::endl;
std::cout << Cell<Tag::id<0> >::id() << std::endl;
return 0;
}
0378デフォルトの名無しさん2011/06/01(水) 11:34:20.64
型消去でSTL仕様のアロケータの型を消そうかと思ったんだけど
rebindできないことに気がついた。これって解決不能だよね?

class hoge{
vector<fuga, type_erased_alloc> v;
template <class A> hoge(A const &a) : v(a) {}
};

みたいな感じで使いたいんだけどどうにかならないかな
0379デフォルトの名無しさん2011/06/01(水) 20:27:47.16
>>378
型消去の意味が解らんけど
aをvに複製するのであればアロケーターを置き換えることは可能。
0380デフォルトの名無しさん2011/06/01(水) 20:29:12.86
>>377
実行時の値はどうでもいいんだからそれ意味なくね。
0381デフォルトの名無しさん2011/06/01(水) 23:31:56.08
>380
2回目のTag2の定義でエラーになるということがポイント。
こうすることで、この名前空間におけるTag2の唯一性を検証できる。


>378
type erasureは型情報をplaceholderの外には出せない……と思う。
使うときに明示的に変換するか、マルチディスパッチするメソッドを用意する(>202)しかないんじゃない?

単に格納するだけだったらboost::shared_ptr<boost::any>の方が簡単だと思う。
0382デフォルトの名無しさん2011/06/02(木) 00:42:44.07
>>381
いや、話の流れからすると>>373の悩みは、struct Xやstruct Argsを
シンボル名代わりに使ってみたけど、あとからenum Argsとか定義する事になったら
struct Argsが衝突しちゃうじゃん、他の宣言と干渉しない手っ取り早い
シンボルって作れないの?って事だと思う。
0383デフォルトの名無しさん2011/06/02(木) 08:47:52.63
型消去の意味が分からない人は型消去かtype erasureでぐぐっといた方がよさげ
(この界隈限定で)割とメジャーな言葉だと思うし
0384デフォルトの名無しさん2011/06/02(木) 20:19:53.79
>>383
1.delegateの仕組み
2.genericsのように入り口と出口だけ型を制限し、
Objectの中ではvoid*のような極端な抽象型を使う仕組み

どっちでも無いようにみえるけど具体的に何なん?
0385デフォルトの名無しさん2011/06/02(木) 21:53:36.58
>384
2の逆。
placeholderの中では具体的な型情報を持っているけど、placeholderを管理するholderは
型情報を持たない抽象型を扱う。
boost::anyが実装例。

>382
型の特殊化を併用すれば名前の浪費は防げるね。
0386デフォルトの名無しさん2011/06/02(木) 22:14:20.20
>>385
Delegate<Child(int,int,int)> method[]=
{
  &functor,          //Child operator(int,int,int);を定義しているオブジェクト
  &function,         //Child function(int,int,int); 普通の関数
  Type(),             //Child(int,int,int);コンストラクター Typeは空のクラス
   Delegate<Child(int,int,int)>(&object,&Class::Method) //オブジェクトと関数のペア
};

だからこういうヤツでしょ。
この例だと内部でvirtual Child operator(int,int,int)を定義したオブジェクトで個々の型をラップしてある。

しかし、>>378が何をしたいのか解らん。まずtype_erased_allocが自作のクラスなのか
hogeの外で定義されたテンプレート引数なのか。そもそもアロケータの型を消すってのも
何を指してるのか解らんし。
0387デフォルトの名無しさん2011/06/02(木) 22:16:18.45
>>385
特殊化でっていうのは>>369のヤツのようなこと?
0388デフォルトの名無しさん2011/06/02(木) 22:44:09.90
>386
boost::any見ろって。
boost::anyにはどの型のオブジェクトでも保存できるけど、boost::anyには
保存している型の(静的な)情報が含まれない。
>386 はAdapterパターン?
0389デフォルトの名無しさん2011/06/02(木) 22:47:54.96
>387
いや、こんなの。

template<int i> class Tag;
template<> Tag<0> : public CellTagBase<Tag<0> > {};
// template<> Tag<0> : public CellTagBase<Tag<0> > {}; --> error
0390デフォルトの名無しさん2011/06/02(木) 23:08:44.21
>>388
http://d.hatena.ne.jp/anonymouse_user/20110109/1294590115
こっからパクってきた。見れば解るがAdapterを内部で生成してる。
これをAdapterパターンというのかは知らん。

boost::anyには静的な情報が含まれないってのはテンプレート引数に
実体の型情報が無いって事だろ。
0391デフォルトの名無しさん2011/06/02(木) 23:17:07.27
>>389
ああ>>377のコードを対象にレスしてたのね。
0392デフォルトの名無しさん2011/06/03(金) 00:00:36.40
template <class T> struct type_erased_alloc
{
struct holder_ { virtual ~holder(){}; virtual void *allocate(size_t s) = 0; /*その他のメンバ*/ };

template <class A> holder : holder_ {
typename A::template rebind<T>::other a;
holder(A const & a) : a(a) {}
void *allocate(size_t s) { a.allocate(s); }
/*その他のメンバ*/
};

template <class U> struct rebind
{
typedef type_eraseed_alloc<U> other;
};

holder_ *p;

template <class A> Hoge(A const & a) : p(new holder<A>(a)) {}

template <class U> Hoge(Hoge<U> const & other) ; // これが書けない
};

こんな感じでrebindができなくなってしまう。やっぱ無理か
コンパイル切るためにクラステンプレートからテンプレートコンストラクタにしたいんだが・・・
0393デフォルトの名無しさん2011/06/03(金) 00:43:22.84
>>392
変な所が多すぎてどう問題をとらえていいか解らん。

1.Hogeってtype_erased_allocのコンストラクター?
2.type_erased_alloc自体にallocateが要るんじゃないの?
3.holder_ *pはどこで使われるの?
4.これが書けないっていうのは、関数の宣言の部分が書けないの?
それとも関数本体の内容の書き方がわからないの?
5.宣言の問題だとしたら、type_erased_allocのTがUで取れないって事?
6.どうでもいいけどtemplate<class A>のあとのclassが抜けてね?
0394デフォルトの名無しさん2011/06/03(金) 02:26:15.01
>392
そりゃムリじゃね? テンプレートコンストラクタが受け取った型情報はあくまで関数内に閉じ込められたものだし。
Aの情報はholderに閉じ込められるからtype erasureとしての価値があるわけで、Hogeに残っていたら
意味ないだろ。まあ、ソースコードが良く判らんから何とも言えんが。
0395デフォルトの名無しさん2011/06/03(金) 02:28:45.10
単にコピーコンストラクタを書きたいのなら、boost::anyのcloneあたりの実装を参考にするのが良いと思う。
あるいは型に依存した色々な処理を行いたいのなら、動的なマルチディスパッチしか無いですな。
そっちは>202参考

というか素直にvector<boost::shared_ptr<boost::any> > 使え。
0396デフォルトの名無しさん2011/06/03(金) 20:44:02.27
>>392
コードが足りなすぎてよくわからんけど、holder_を外にだせばいいだけじゃないの?
あともう一つ、コピコンで受け取ったHoge<U>をさらにholderで包むこともできんじゃないの?
ともかく正確なコードを書いてもらわんと解らん。ただし別にallocatorの規格で決まってる部分は
書かなくていいよ。手を加えたとこだけ見せてくれ。
0397デフォルトの名無しさん2011/06/12(日) 18:51:32.30
::type

↑

これウザくない?
結果が組み込み型とかになるならまだしもさ
継承とかできるならして::type書かなくていいようにすればいいじゃん
なんでみんなこんなだるい書き方するの?
0398デフォルトの名無しさん2011/06/12(日) 18:56:14.99
>>397
まずはお手本よろしく。
0399デフォルトの名無しさん2011/06/12(日) 19:33:35.74
>>373 みたいに、最後で評価するようにすればいいだろ。
まぁ、それでも1回は必要になるだろうけど。
0400デフォルトの名無しさん2011/06/12(日) 21:42:21.21
>>397
ちなみにそれは0xになっても型の遅延評価として残り続ける。
0401デフォルトの名無しさん2011/06/13(月) 08:23:29.69
>>387
テンプレートエイリアスを使え

template < typename T > using add_ptr = typename std::add_pointer<T>::type ;
add_ptr<int> ptr ; // int *
0402デフォルトの名無しさん2011/06/13(月) 21:14:52.66
今無いものを言われてもねぇ。
VC6,0の悲劇を繰り返す気かい。
0403デフォルトの名無しさん2011/06/15(水) 23:33:55.05
そこでマクロですよ
0404天使 ◆uL5esZLBSE 2011/07/06(水) 09:23:09.35
これ ; デリミタっていうんだけどさ、これをつけなきゃエラーになるような
そんな言語使ってる奴ってどうみてもゴミだと思うんだけど

もしかして「;」これ打ち忘れてコンパイルエラー出すのが楽しいの?
そうか、二度と話かけんなよ

結局ただのゴミだったんだな
0405デフォルトの名無しさん2011/07/06(水) 12:12:15.53
数学板で猫が暴れているのと同じように、この天使というコテもそのポジションになりうるのだろうか。
0406デフォルトの名無しさん2011/07/06(水) 21:01:18.67
こんなクソみたいな発言しているんじゃダメだろ。
0407デフォルトの名無しさん2011/07/06(水) 21:09:15.88
猫もクソみたいな発言しかしないよ。
0408デフォルトの名無しさん2011/07/13(水) 06:20:07.21
猫のクソみたいな発言しかしないよ。
0409デフォルトの名無しさん2011/09/08(木) 16:50:30.76
下のプログラムは、MinGW (gcc4.5.2)では一応、正しい結果がでますが、VC++2008(SP1)では
次のコンパイルエラーが出ます。VC++2008の問題なのか、それともプログラムに問題ありなの
か教えて下さい。お願いします。

error C2593: 'operator +' があいまいです。
'std::complex<double> operator +<double>(std::complex<double>,double)' の可能性があります。
または 'std::complex<double> std::operator +<double>(const std::complex<double> &,const double &)'
[引数依存の照合を使用して検出しました] の可能性があります
   ↓
0410デフォルトの名無しさん2011/09/08(木) 16:50:55.54

template <class T>
struct double_trait {
typedef T type;
};

template<>
struct double_trait<int> {
typedef double type;
};

template<>
struct double_trait<float> {
typedef double type;
};

template <class T>
std::complex<T> operator + (std::complex<T> z, typename double_trait<T>::type c)
{
return z+c;
}

int main()
{
using namespace std;

complex<double> z(0,1);
cout<< z+1 <<endl;
...
}
0411デフォルトの名無しさん2011/09/08(木) 18:20:40.43
型がdoubleのときにVC++2008付属のSTL(Dinkumware)の中で

complex<double> operator+(complex<double>, double)

に相当するものが既に定義されていて、テンプレートパラメータT=double
のときに実質、2重に定義されてしまうんですかねぇ。
でも、gccのSTL(SGI)ではなぜエラーにならないんだろう?

まあ、Z+1の代わりにz+1.0とすればいいだけの話なんですが。
0412デフォルトの名無しさん2011/09/09(金) 00:43:28.64
VCのバグ
04134092011/09/09(金) 15:04:05.19
普通の演算子オーバーロードにすると、gccもVC++も動きました。
complex<float> zのサイズが8でもz+1のサイズは16になっているのが
謎ですが、これは<complex>内でコンストラクタテンプレートが用いら
れているからでしょうか?

#include "stdafx.h"
#include <complex>

std::complex<double> operator + (std::complex<double> z, int c)
{
return z + (double)c;
}

int main()
{
using namespace std;

complex<float> z(0,1);
char c=1;

cout<<sizeof(z)<<endl;
cout<<sizeof(z+1)<<' '<<z+1<<endl;

int i; cin>>i;
return 0;
}
結果
8
16 (1,1)
0414デフォルトの名無しさん2011/09/09(金) 15:07:04.11
訂正:z+1→z+c
0415デフォルトの名無しさん2011/09/09(金) 20:14:14.66
お前がcomplex<double>を返してるから
0416デフォルトの名無しさん2011/09/09(金) 21:38:45.81
そうだが、その前にcomplex<float>からcomplex<double>に変換する
コピーコンストラクタがないと、コンパイルエラーが出るはずなのに
なんで出ないのか? と言うのが本当の質問の意味だが。
0417デフォルトの名無しさん2011/09/09(金) 22:22:05.58
規格読んでるのかい?
0xdraft 26.4.3
template<> class complex<double> {
public:
typedef double value_type;

constexpr complex(double re = 0.0, double im = 0.0);
constexpr complex(const complex<float>&);
explicit constexpr complex(const complex<long double>&);
0418デフォルトの名無しさん2011/09/10(土) 08:40:12.02
ふーん、constexprは次世代C++に正式に導入さっるのか?
また、複雑さを持ち込んでいるような。

そもそも、ちょっと前のgccやVC++2008に導入されてるのか?
0419デフォルトの名無しさん2011/09/10(土) 09:48:17.16
ISO/IEC 14882:2003 26.2.3
template<> class complex<double> {
public:
typedef double value_type;
complex(double re = 0.0, double im = 0.0);
complex(const complex<float>&);
explicit complex(const complex<long double>&);

つーかもうTMP関係ないだろ
0xスレなり初心者スレなりにいけ
0420デフォルトの名無しさん2011/09/10(土) 10:20:47.29
complex<double> と complex<float>は別のクラスだから
型変換するためにコピーコンストラクタが必要だと思った
が、クラステンプレートを実体化した後なら普通のコピー
コンストラクタでokということか。

0421デフォルトの名無しさん2011/09/10(土) 11:07:26.16
用語は正しく理解し使え。
話題にしてるのはコピーコンストラクタでなく
complex<float>からcomplex<double>への(暗黙の変換も可能な)変換コンストラクタ。
流れで通じてるからってそれに甘えるな。
0422デフォルトの名無しさん2011/09/10(土) 11:15:16.79
変換コンストラクターと変わらないのに、
あえてコピーコンストラクターと特別な呼び方するのってなんでだろ。
コピコン未定義だと暗黙の代入されるけどあれはしょせんC互換のコピーだし
コンストラクター書くときに、変換コンストラクターとコピコンの区別を意識した事がない。
0423デフォルトの名無しさん2011/09/10(土) 11:45:21.23
>>421

うぜぇ。カス!重箱の隅つついた事しかいえんのか?
0424デフォルトの名無しさん2011/09/10(土) 11:52:17.58
>>422
explicitを指定しないコンストラクターはすべて、変換コンストラクターである。
コピーコンストラクターも変換コンストラクター。
コピーコンストラクターを定義するのは、それが特別な定義を必要としているから。
例えば、ユーザー定義のコピーコンストラクターがあれば、暗黙のコピーコンストラクターは生成されないなど。
0425デフォルトの名無しさん2011/09/10(土) 12:00:08.50
>>423
>>418にも突っ込んどいたら。仕様に対する個人の感想なんかいらんわ、聞きたいことだけ聞け。カス!って
0426デフォルトの名無しさん2011/09/10(土) 12:32:04.98
コピーコンストラクタと変換コンストラクタを区別してない人って多いのか?
自分でクラスを書くときには単に必要なメンバ関数の一つという意味で区別する意識はなくてもいいけど
他人と話すときははっきり区別しないと言いたいことが正しく伝わらないんじゃないか?
0427デフォルトの名無しさん2011/09/10(土) 14:59:14.90
多いわけない。
コピーコンストラクタがなんであるか知らない奴なんて初級ちゃん。
0428デフォルトの名無しさん2011/09/10(土) 15:29:52.94
やれやれ、ゴミ共がすぐ湧いてくる。



0429デフォルトの名無しさん2011/09/10(土) 16:03:56.07
>>1-428
よう、ゴミ共
0430デフォルトの名無しさん2011/09/10(土) 17:32:39.75
これで、このスレは、しばらく過疎化します。

しかし、何でこのスレというか、C++スレには「俺は何でも知ってるぞ!」
と自己主張すぎる奴が多いのかね。若気のいたりかw

規格書を読め? お前はパリサイ人か! こいつ、天狗になって職場とか
掲示板でも嫌われてるだろ。

VC++ラウンジにもそういう奴いるし。

C++の固有の決まりなんて知るか!だから、C++が嫌われるんだ。糞が

0431デフォルトの名無しさん2011/09/11(日) 19:31:28.57
>>424
いや変換コンストラクターの一種であるコピコンが存在する事がおかしいとは言ってないよ。
わざわざ同じクラスに変換する変換コンストラクターを、わざわざなんでコピコンって呼ぶのってのが疑問なんで。
0432デフォルトの名無しさん2011/09/11(日) 19:33:49.56
>>427
変換コンストラクタとコピーコンストラクタの違いって何?
「暗黙で生成される」と「クラスと同じ型を引数にとる」以外で。
0433デフォルトの名無しさん2011/09/11(日) 20:25:44.37
explicit指定がなくて引数をとるやつが変換コンストラクタ
非テンプレートで第1引数が自分と同じ型で第2引数以降がないか省略可能なやつがコピーコンストラクタ

コピーコンストラクタは変換コンストラクタの一種ってわけじゃなく別の概念
0434デフォルトの名無しさん2011/09/11(日) 20:35:28.49
>>433
よくわからん。

int a;
string b;
Numeric n,m;
n = static_cast<Numeric>(a); //変換コンストラクタ
n = static_cast<Numeric>(b); //変換コンストラクタ
n = static_cast<Numeric>(m); //コピコン

n = Numeric(a); //変換コンストラクタ
n = Numeric(b); //変換コンストラクタ
n = Numeric(m); //コピコン

n = a; //変換コンストラクタ
n = b; //変換コンストラクタ
n = m; //コピコン

n = Numeric( "100", 8 ); // 通常コンストラクタ
0435デフォルトの名無しさん2011/09/18(日) 15:34:34.38
何らかの型Tがあって、その型は組み込み型か組み込み型への変換演算子を持っていると期待出来る。
最終的には型をlong, unsigned long, doubleのいずれかに変換したい。
というときに、型Tを最も適当に変換出来る型を取得するにはどうしたらいいだろうか?

template<typename T>
struct ConvertResult { typedef ??? type; };
template<typename T>
typename ConvertResult<T>::type convert(T t);

struct X { operator int(); }; // intへ変換可能

long n = convert(X()); // longになって欲しい
0436デフォルトの名無しさん2011/09/18(日) 16:02:28.92
>>435
まず「最も適当」を定義してもらう必要があるんじゃなかろうか。
0437デフォルトの名無しさん2011/09/18(日) 17:00:11.98
>>436
元が組み込み型と変換不能な型は場合わけが出来るので問題ない。
浮動小数点数に変換出来る型は符号の有無が無いので多重定義で分類出来る。
整数型に変換出来る型だと整数の昇格があるので縮小変換と拡大変換が
同格になるのが問題だった。
http://codepad.org/sGDXhSYH
http://codepad.org/xhR2bnXx
0438デフォルトの名無しさん2011/09/18(日) 21:41:25.13
>>433

別にどうでもいいやん。

Aクラスから全く別のクラスBに変換するのならあってもいいが。
しかし、そんな状況はクラス設計が終わっとる

ただ、単にintからlongに変えるだけで値は変わらんでしょ。
暗黙の型変換演算子か、コンストラクタテンプレートをもっただけでしょ。

やたらと新しい概念を持ち込む「禿ども」、そしてそれを有り難がってる
「日本の馬鹿達」がうざい。
0439デフォルトの名無しさん2011/09/18(日) 21:56:01.39
>>435
ConvertResult::operator long();
ConvertResult::operator unsigned long();
ConvertResult::operator double();
ConvertResult::type使わずこういう使えばいいんじゃね。
0440デフォルトの名無しさん2011/09/19(月) 14:55:31.66
魔法の呪文
#if __cplusplus >= 201103L
を打ちまくって気分だけでもC++2011を味わえばいい
#else
の妥協部分にも妙案が出てくるかもしれんし
0441デフォルトの名無しさん2011/09/23(金) 03:02:38.76
>>438
外国はどうよ。日本よりはましか?
0442デフォルトの名無しさん2011/10/12(水) 23:52:30.41
http://codepad.org/VbGFMpCW
templateで与えられた構造体のサイズを最小にしたくて頑張ってるんだけど
上のコードのFoo0〜Foo5を自動で生成することはできないかな?
今は構造体ごとにスクリプトで生成してるんだけどC++だけでできるなら(マクロなしで)教えて欲しい
変数名がでたらめならできるんだけどtemplateパラメータの順番と変数名のマッピングが崩れないようにしようとすると詰まった
0443デフォルトの名無しさん2011/10/13(木) 00:34:14.96
template<typename A,typename B,typename C>struct small{
template<typename E,typename F,typename G>struct asmb_t{E x0;F x1;G x2;};
template<typename E,typename F,bool G=sizeof(E)<=sizeof(F)>struct cmp_t{typedef E t;};
template<typename E,typename F>struct cmp_t<E,F,false>{typedef F t;};
typedef asmb_t<A,B,C> v0;
typedef asmb_t<A,C,B> v1;
typedef asmb_t<B,A,C> v2;
typedef asmb_t<B,C,A> v3;
typedef asmb_t<C,A,B> v4;
typedef asmb_t<C,B,A> v5;
typedef typename cmp_t<v0,typename cmp_t<v1,typename cmp_t<v2,typename cmp_t<v3,typename cmp_t<v4,v5>::t>::t>::t>::t>::t type; };
0444デフォルトの名無しさん2011/10/13(木) 00:37:22.55
あ、ごめ要点全然外れてたw
0445デフォルトの名無しさん2011/10/26(水) 02:56:03.92
こういうコードの様に特殊化と実体の無いテンプレートを駆使してみたら?
http://codepad.org/Voh18mFU
0446デフォルトの名無しさん2011/11/14(月) 08:49:41.89
カウンタを定数で回すforがほしいんだけど、TMPでできませんか?

template<int i> struct func{
void operator()(){
//カウンタが定数なので配列の長さや他のtemplate引数に使える
int a[i]; sprintf_s<i>(a, "%d", 12345);
}
};
static const int start = 0, end = 3;
static_for<start, end, func>();

を

{func<0> f; f();}
{func<1> f; f();}
{func<2> f; f();}

に展開するようなイメージ。
0447デフォルトの名無しさん2011/11/14(月) 09:19:14.46
本題と違うところにツッコミだけど、 sprintf_s は黙って結果を切り捨てたりしないぞ。
0448デフォルトの名無しさん2011/11/14(月) 10:34:18.62
template <int i, int j, class F> class For {
F f;
public:
For(F f) : f(f) { }
void operator () (void) const {
f();
For<i + 1, j, F> g(f);
g();
}
};

template <int i, class F> class For<i, i, F> {
F f;
public:
For(F f) : f(f) { }
void operator () (void) const { }
};

class F { public: void operator () (void) const { std::cout << "Hello" << std::endl; } };

int main(void) {
F f;
For<0, 2, F> g(f); // [0, 2)
g();
return 0;
}

こんなん?
04494462011/11/14(月) 16:39:03.77
>>447 ランタイムエラーでしたっけ。
数値のテンプレート引数を渡すものがぱっと思い浮かばなかったのでこれにしました。

>>448 ありがとうございます。
なるほど、こういう再起を作ればいいのか。
慣れてしまえば単純なんだろうけど、どうしても再起が直感的にわからなくて。
カウンタ定数を関数に渡したいので、ちょっと改造させてもらいました。
04504462011/11/14(月) 16:39:33.78
template <int i, int j, template<int> class F> class For{
F<i> f;
public:
void operator () (void) const {
f();
For<i + 1, j, F> g;
g();
}
};

template <int i, template<int> class F> class For<i, i, F> {
F<i> f;
public:
void operator () (void) const { }
};

template<int i>
class F{
public:
void operator () (void) const {
char a[i]; sprintf_s<i>(a, "%d", i);
}
};

int main(){
For<2, 5, F> g; //[2, 5)
g();
return 0;
}
04514462011/11/14(月) 17:04:27.39
あとは関数オブジェクトじゃなくてラムダ関数が渡せれば最高なんだけど
templateラムダ関数なんてないしなぁ…
■ このスレッドは過去ログ倉庫に格納されています