C++相談室 part60
..
287:デフォルトの名無しさん
08/01/29 22:36:43
あるクラスを継承しているクラス群のみを対象にメモリ割り当てをカスタマイズしたいです
class Base{}
class Derived1 : public Base{}
class Derived2 : public Base{}
そこでこれらクラス群の内、最も大きいサイズのクラスを基準に配列を静的に用意、
Base、Derived1、Derived2をnewする時に使いたいと思ってます
struct AllocUnit{ char[???] buf;} ←ここのバッファのサイズを静的に求めたい
static AllocUnit[MAX_UNIT] memory; //sizeof(AllocUnit)*MAX_UNIT分のバッファを静的に確保
???の部分を求める方法がわかりません
MPLを使えばできそうな感じなんですが・・・
言い換えると、任意の数のクラスの内、サイズが最大のものをコンパイル時に取得する方法はないか?
という事です↓こんなイメージ
char[max_size<Base,derived1,derived2>] buf;
288:デフォルトの名無しさん
08/01/29 22:49:25
>>264
俺はそういう時、
template <class T1, class T2>
class A { ... public: typedef A<T1, T2> this_t; };
として、バインドするクラスは
template<class T1>
class AInt : public typedef A<T1, int>{};
のようにpublicで継承する。
そしてクラスを記述する時はどんなものにしろ必ず
A::this_t;
AInt::this_t;
と最後に::this_tとつける気持ち悪い習慣を身に着けている。
もしくは、 #define hogehoge(class) class::this_t のようなマクロを使うとか、いろいろ手はあるけど
結局どれもいたちごっこかうへへへへへへへへへh
289:デフォルトの名無しさん
08/01/29 22:55:38
>>287
こんなのでどう
template <typename A, typename B> struct max_size { enum{ value = sizeof(A) > sizeof(B) ? sizeof(A) : sizeof(B) }; };
template <typename A, typename B> struct max_size_chain { enum{ value = A::value > sizeof(B) ? A::value : sizeof(B) }; };
template <typename A, typename B, typename C> struct max_size3: max_size_chain<max_size<A, B>, C>{};
template <typename A, typename B, typename C, typename D> struct max_size4: max_size_chain<max_size3<A, B, C>, D>{};
template <typename A, typename B, typename C, typename D, typename E> struct max_size5: max_size_chain<max_size4<A, B, C, D>, E>{};
char buf[max_size5<char, int, short, long, void*>::value];
290:デフォルトの名無しさん
08/01/29 22:57:36
boost mpl if_cとかとsizeof使えばいい
291:デフォルトの名無しさん
08/01/29 22:57:48
template <size_t x, size_t y> struct size_t_max {
static const size_t value = x > y ? x : y;
}
struct AllocUnit {
static const size_t size = size_t_max<sizeof Derived1, sizeof Derived2>::value;
char buf[size];
}
基底クラスより派生クラスの方がサイズ大きいの分かってるから
2つの比較だけでいいべ。
292:デフォルトの名無しさん
08/01/29 22:58:38
ミスって途中送信してる・・・。
こっちが本物。
#include <iostream>
struct Base { int x; };
struct Derived1 : public Base { int n; };
struct Derived2 : public Base { int n, m; };
template <size_t x, size_t y> struct size_t_max {
static const size_t value = x > y ? x : y;
};
struct AllocUnit {
static const size_t size = size_t_max<sizeof (Derived1), sizeof (Derived2)>::value;
char buf[size];
};
int main(){
std::cout << AllocUnit::size << std::endl;
}
基底クラスより派生クラスの方がサイズ大きいの分かってるから
2つの比較だけでいいべ。
293:244
08/01/29 23:09:34
皆さんどうもありがとうございます。
なるほど、テンプレートの特殊化を利用って感じですか? こんな風に使えるんですね。
が、しかし、
>>285
>「ポインタで与えられる」、しかし共通のベースクラスがあるわけではないってことは、void *型で渡すんだろうか。
ビンゴでございます。テンプレートの場合変数の型で挙動が変化してるわけですよね。
自分は Objective-C も使うことがあるので今回のような疑問を持ったのですが。
>しかし、既存のコードはいじりたくないので、共通のベースクラスに純粋仮想関数は使えないというのなら、
とりあえず多重継承で共通のベースクラスを足すことをを検討しています。
>例えばBoost.Anyに使われているType Erasureのテクニックが使えるかもしれない。
そうですか、参照してみます。
294:244
08/01/29 23:15:51
あ、あれ、でもvoid *で渡さなくてもいいかな? ちょっと考えてみます。
でもやっぱ多重継承の方が自然かなあ。
295:287
08/01/29 23:16:19
>>289
ありがとうございます。参考にします
>>292
なるほど。確かにsizeof(Base)<=sizeof(Derived)ですもんね
よく考えたらgreater<T1,T2>的なモノを用意して、それを連ねていくだけでよかったんですね
しかし派生クラスの数が増えるたびにmax_sizeの引数増加版を定義するのが面倒・・
可変引数のtemplateがあればなぁ・・・
296:デフォルトの名無しさん
08/01/29 23:20:40
>>287
template<typename T1, typename T2, typename T3>
struct MaxSize {
typedef typename if_c<(sizeof(T1) > sizeof(T2)),
typename if_c<(sizeof(T1) > sizeof(T3)),T1, typename if_c<(sizeof(T2) > sizeof(T3)),T2,T3>::type>::type,
typename if_c<(sizeof(T2) > sizeof(T3)), T2, T3>::type >::type SizeT;
static const size_t sz = sizeof(SizeT);
};
297:デフォルトの名無しさん
08/01/29 23:27:59
マクロをゴニョゴニョすれば
DEFINE_MAX_SIZE(3, 100);
で max_size3〜max_size100 まで定義、みたいなこともできそうだが、
実用的には生成プログラム書いた方が楽だと思う。
298:デフォルトの名無しさん
08/01/30 14:46:54
C++で継続(continuation)、あるいはそれっぽいことができるライブラリや、
C++で継続に関するページがあれば教えてください。
299:デフォルトの名無しさん
08/01/30 15:44:42
まずお前の継続に関する経験について聞こうか?
全くC/C++以外の経験が無いとかいうレベルだとかなり大変だぞ。
300:デフォルトの名無しさん
08/01/30 16:21:20
>>299
rubyでcallccを知り、その関連ページで勉強した程度しか知識がありません。
やりたいことは、まさにrubyのcallccで実行できるようなことです。
301:デフォルトの名無しさん
08/01/30 16:34:55
「なんでも継続」は読んだ?
(Cの)setjmp/longjmpは理解してる?
302:298
08/01/30 16:40:15
>>301
「なんでも継続」のページ、良さそうですね。
まずここから始めてみます。
setjmp/longjmpは、Unix C上がりなので知ってます。使った記憶は1回しかありませんが…。
303:デフォルトの名無しさん
08/01/30 18:00:53
>>298
Boost.Coroutine
Hamigaki C++ Libraries
304:デフォルトの名無しさん
08/01/31 00:14:39
Hamigakiってなんかのギャグかと思って調べたらほんとにあるんだな…。
305:デフォルトの名無しさん
08/01/31 00:17:48
なんか最近はスーパーマリオみたいなのつくってなかったっけ
306:デフォルトの名無しさん
08/01/31 07:01:14
BoostにLokiのタイプリストみたいなものってありありますか?
307:デフォルトの名無しさん
08/01/31 08:16:40
cons list?
308:デフォルトの名無しさん
08/01/31 14:59:51
>>306
Boost.MPLのmpl::vector等
309:デフォルトの名無しさん
08/01/31 18:29:56
>>308
は?
310:デフォルトの名無しさん
08/01/31 21:06:00
>>309
へ?
311:デフォルトの名無しさん
08/01/31 21:18:01
>>310
ん?
312:デフォルトの名無しさん
08/01/31 22:17:13
>>311
え?
313:デフォルトの名無しさん
08/01/31 22:18:19
>>312
ろ?
314:デフォルトの名無しさん
08/02/01 00:43:26
>>313
す?
315:デフォルトの名無しさん
08/02/01 00:49:58
>>314
け?
316:デフォルトの名無しさん
08/02/01 01:17:15
やめんか
317:デフォルトの名無しさん
08/02/01 05:30:19
C++的に配列はどんなものでも<vector>ライブラリを使うべきなんでしょうか?
318:デフォルトの名無しさん
08/02/01 05:43:56
>>317
そんなことはないけど、 ruby や python みたいな言語を触ってる人から見て
配列といって当てはまるのは std::vector でしょうね。組み込みの配列はいろいろ
歴史的な問題も残ったままだし。
319:デフォルトの名無しさん
08/02/01 07:29:58
>>317
サイズが完全に決まってるなら
巨大でさえなければ、
組み込みの配列を使った方が効率がいい。
320:デフォルトの名無しさん
08/02/01 07:53:11
tr1::array早く来い来い。
321:デフォルトの名無しさん
08/02/01 12:08:03
普通の配列ならスタックに蓄えられるとか、newすればヒープから領域を取ってくるとか、
配列を扱うならそこら辺の知識もあってほしいな。
322:デフォルトの名無しさん
08/02/01 14:50:07
alloca()
323:デフォルトの名無しさん
08/02/01 21:09:38
まぁ、スタックに蓄えられるとか、newすればヒープから領域を取ってくるとか
規格には書いてないけどな
324:デフォルトの名無しさん
08/02/01 21:12:53
new はフリーストアから領域を取ってくるんです!
325:デフォルトの名無しさん
08/02/01 21:18:22
mallocはヒープから領域を取ってくるんです!
326:デフォルトの名無しさん
08/02/02 02:37:39
stroustrupはどこから毛を取ってくるんです!?
327:デフォルトの名無しさん
08/02/02 03:14:27
>>326
お前らがnewするたび、stroustrupから領域を割り当てられているのに
ちゃんとdeleteしない奴が多いから…。
そろそろstd::bad_allocが飛んでくるぞ。
328:デフォルトの名無しさん
08/02/02 12:39:36
stroustrup「virtual hair hair() = 0 はただのインタフェース!
実際のインスタンスはもっとふさふさなの!
バヤには見えないんだよーだバーヤバーヤ!」
329:デフォルトの名無しさん
08/02/02 13:50:24
散々ネタに去れてるのにstroustrupのAAってなんでないんだろう。
俺が作ってやる。
330:デフォルトの名無しさん
08/02/02 21:17:56
URLリンク(www.raw-paradise.com)
331:デフォルトの名無しさん
08/02/04 12:00:17
毛量保存の法則
頭髪の少い場合、顎髭や胸毛、ギャランドゥなどで補い、最終的な毛量は一定
332:デフォルトの名無しさん
08/02/04 12:15:26
ハゲで体毛も薄い人間は
代わりに心臓に毛が生えまくってるとか
333:デフォルトの名無しさん
08/02/06 04:31:06
URLリンク(www.research.att.com)
> C++ explicitly allows an implementation of delete to zero out an lvalue operand
これ訳すと
「C++ は delete の実装が左辺値である対象をゼロにすることを明示的に許している」
ってことだよね?
int* p = new int;
delete p;
delete した時点で p == 0 になるような実装もアリってこと?
規格見てもそんなことしていいなんて記述は見当たらなかった。
それとも、ただの読み違い?
334:デフォルトの名無しさん
08/02/06 06:32:38
そうだよ。
auto_ptrあたりなんかはそれを頼りに実装してる
335:デフォルトの名無しさん
08/02/06 07:40:08
食い違ってるような
336:デフォルトの名無しさん
08/02/06 07:52:37
許しているだけなのにそれを頼りにしちゃいかんのでは。
337:デフォルトの名無しさん
08/02/06 08:26:25
便利のようでそうでもないかな。変な副作用はなさそうだから気にしないでおこう。
最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
5030日前に更新/95 KB
担当:undef