C++相談室 part60
..
175:デフォルトの名無しさん
08/01/26 03:01:40
>>173
詳しく有難うございます。納得できました。
>>174
「構文」は間違いでした。>>173のような事を表したかったのですが、
そういう場合は何と呼ぶべきですかね…
176:デフォルトの名無しさん
08/01/26 03:20:13
>>175
つか、何がしたいの?
177:デフォルトの名無しさん
08/01/26 04:53:51
今タイピングのアルゴリズムでゲーム中に「し」を「si」と「shi」のどちらでも受け付けるとような操作を考えています。
現段階では文字列クラスを用意して双方向リンクリストを使って分岐を操作して居るんですが、どうしてもコードが複雑になってしまいます。
もう少し簡単なアルゴリズムや便利なSTLなどがあったら教えてください。
文字列クラス
class characterData
{
private:
wchar_t ch; // 単語を構成する文字
Databace* follow; // この文字に続く文字へのポインタ
Databace* other; // 分岐文字へのポインタ
Databace* rear; // この文字の前の文字へのポインタ
public:
Databace(); Databace(wchar_t, Databace*, Databace*, Databace*, unsigned char); ~Databace();
// 変数の値を設定する関数群
void setFollow(Databace*); void setOther(Databace*); void setRear(Databace*); void setCh(wchar_t); void setLevel(unsigned char);
// 変数の値を返す関数群
wchar_t getCh() const; Databace* getFollow() const; Databace* getRear() const; Databace* getOther() const;
};
文字列を作るクラス
class createString
{
private:
Databace* end; // 文字列の最後の文字へのポインタ
Databace* div; // 分岐文字がある場合のみendと違う場所を指す
void add(const int n, ...); // n個の文字を追加する
public:
CStrManage(); ~CStrManage();
// elementをローマ字に変換しbaseの後ろに追加する
bool convert(const wchar_t* element, Databace* base);
};
178:デフォルトの名無しさん
08/01/26 05:00:27
追加用の関数はこうなっています
void createString::add(const int n, ...) {
va_list args_pointer; wchar_t* arg_wchar; size_t length;
va_start(args_pointer, n);
// 文字を分岐させる
for(unsigned char i=0; i<n; i++) {
arg_wchar = va_arg(args_pointer, wchar_t*);
length = wcslen(arg_wchar);
// 分岐用文字列を作成する
Databace cdb; // ダミーの作成
Databace* tmp = &cdb; // 追加先の指定
Databace* rear = NULL; // 現在地の記憶
// 文字の追加
for(unsigned char s=0; s<length; s++) {
Databace* data = new Databace();
if(s==0) { rear = data; } // 追加前の場所を記憶
// 文字データの設定
data->setFollow(NULL); data->setOther(NULL); data->setCh(arg_wchar[s]); data->setLevel(s + 1);
if(s==0) { data->setRear(end); } // 前の文字を参照させる
else { data->setRear(rear); } // 新しく作った文字列の先頭を参照させる
// 文字を追加
tmp->setFollow(data); tmp = tmp->getFollow();
}
// 作成した文字をデータベースに追加する
if(i!=0) {
div->setOther(tmp2->getFollow()); div = tmp; // 作成した文字を追加
div->setFollow(cdb.getFollow()); div = end; // 分岐後の参照先を設定
} else { div->setFollow(cdb.getFollow()); end = div = tmp; }
}
va_end(args_pointer);
}
179:デフォルトの名無しさん
08/01/26 05:34:13
>>170
sizeof(this) ってポインタのサイズだと思われ
sizeof(*this) にしないとだめなんじゃね?
180:179
08/01/26 05:36:04
って、すでに173で指摘されてた・・・
181:110
08/01/26 06:16:08
>>177
std::listを使って一本のリストを作って、リストの各要素のオブジェクトを工夫したほうがいいよ。
リストクラス自作するにしても、これはあまりにも酷い。
せめてコンパイルが通りそうなコードを読ませてくれ。
182:デフォルトの名無しさん
08/01/26 11:09:34
>>175
そもそも、クラスの初期化を外部から行なってはいけません。
183:156
08/01/26 11:23:55
結局、他の人はどうしてるの?
184:デフォルトの名無しさん
08/01/26 11:48:39
折角階層的にネームスペースを宣言しているのに、ユージング宣言し捲くるってどうなのよ。
そんなばかげたことする香具師いないからレスがつかないんじゃね?
185:デフォルトの名無しさん
08/01/26 11:54:16
using なんて普通は使わないよな。
186:デフォルトの名無しさん
08/01/26 12:04:47
>>166
all.hにはすべてのヘッダファイルではなく、外部から提供されたライブラリのヘッダだけ入れておけば
基本的に更新することはないんじゃない? (その場合、all.hというネーミングは不適切だね。)
187:デフォルトの名無しさん
08/01/26 12:05:50
目的を既に忘れてるな
188:デフォルトの名無しさん
08/01/26 12:18:43
using 宣言は使うだろ。
using しないとコードが汚くなる。
そこらじゅう ns1::ns2::hoge() とか nsN::nsM::hoge() とかばかりになるぞ。
189:デフォルトの名無しさん
08/01/26 12:21:44
ある程度のプロジェクトではファイルの先頭が #include や using で埋め尽くされるのは避けられないこと。
耐えろ。
190:デフォルトの名無しさん
08/01/26 12:22:45
>>188
おまいはヘッダファイルでも using 使って
迷惑かけるタイプか
191:デフォルトの名無しさん
08/01/26 12:26:55
>>190
どっからヘッダファイルで using なんて考えが出てきたんだ?
*.h と *.cpp では書くものが違うのはあたりまえだろうが。常考。
192:デフォルトの名無しさん
08/01/26 12:32:23
using なんて使わなくても
名前空間のエイリアス作ればいいだろ。
193:デフォルトの名無しさん
08/01/26 12:35:08
>>188
namespace fuga1 = hoge1::hogeA::hogeX;
namespace fuga2 = hoge2::hogeB::hogeY;
namespace fuga3 = hoge3::hogeC::hogeZ;
……
みたいな解決策もある。
194:デフォルトの名無しさん
08/01/26 12:36:58
using は関数増えた時に別の関数が選択される恐れがあるから怖い。
エイリアス作ろうぜ。
195:デフォルトの名無しさん
08/01/26 12:40:22
>>194
例は?
using 指令と違って using 宣言では名前が衝突するとコンパイルすら通りませんが?
196:デフォルトの名無しさん
08/01/26 12:41:57
そもそもネームスペースが上手く使われてる大規模プロジェクトって見たことないな。
パッケージ名を接頭辞に持つプロジェクトの方が上手くいってたりする。
197:デフォルトの名無しさん
08/01/26 12:44:54
>>195
そりゃ嘘を教えられたな。
確かにエラーになることは多いが、エラーにならない事もある。
==========
namespace Hoge { void Foo(); }
namespace HogeHoge { void Bar(); }
using Hoge::Foo;
namespace HogeHoge {
void Bar() { Foo(); } ← Hoge::Foo
}
==========
namespace Hoge { void Foo(); }
namespace HogeHoge { void Foo(); void Bar(); }
using Hoge::Foo;
namespace HogeHoge {
void Bar() { Foo(); } ← HogeHoge::Foo
}
198:デフォルトの名無しさん
08/01/26 12:48:05
>>193 の方法でいいんじゃない?
これなら普通は namespace の数 < 識別子の数 なので先頭部分は少し短くなる。
ただし、その代わりにコードは少し長くなる。
どっちにしろ先頭が namespace で埋め尽くされるのは変わらないが。
199:デフォルトの名無しさん
08/01/26 12:54:22
そだよ。エイリアスが一番マシ。
ただ、エイリアスは .cpp のグローバルでのみ作るべし。
名前空間内で作っちゃうとまたややこしい問題が生じる。
200:デフォルトの名無しさん
08/01/26 12:59:57
グローバルで using してたら意味ないだろ。
namespace HogeHoge {
using Hoge::Foo;
void Foo();
}
で普通にエラーでたぞ。
201:デフォルトの名無しさん
08/01/26 13:04:43
>>200
あらホント。
202:デフォルトの名無しさん
08/01/26 13:04:57
namespace Hoge { void Foo(); }
namespace HogeHoge{
namespace Hoge { void Foo(); }
void Bar(){ Hoge::Foo(); } <- HogeHoge::Hoge::Foo
}
別に間違いようはいくらでもある。
203:デフォルトの名無しさん
08/01/26 13:06:33
名前空間って厄介だよな。
204:デフォルトの名無しさん
08/01/26 13:08:55
>>202
これって防ぎようなくね?
どうすんの? これ。
205:デフォルトの名無しさん
08/01/26 13:11:53
>>204
::Hoge::Foo() でアクセスできるよ。
206:デフォルトの名無しさん
08/01/26 13:12:27
>>205
なるほど・・・。
でも、常日頃から :: から始めないと防げないよな。
207:デフォルトの名無しさん
08/01/26 13:13:53
そもそも他人の名前空間と同じ名前の名前空間を
後から作るという時点で間違いだとは思うが、
開発中に後から導入したライブラリが・・・ということもあるか・・・。
208:デフォルトの名無しさん
08/01/26 13:17:40
ちなみにこんなのも。
namespace Fuga { void Foo(); }
namespace Hoge = Fuga;
namespace HogeHoge {
class Hoge { public: static void Foo(); };
void Bar(){ Hoge::Foo(); } <- HogeHoge::Hoge::Foo();
}
209:デフォルトの名無しさん
08/01/26 13:22:31
名前空間はクラス名・関数名・変数名なんかと違って規約がなかったりするから、結構みんなテキトーにつけてたりする。
酷い話だとグループ全員が自分用の関数を mylibs に入れていた例が...
210:デフォルトの名無しさん
08/01/26 13:25:14
幾何学ライブラリで geom が衝突したりとかだな。
211:デフォルトの名無しさん
08/01/26 13:28:54
かといってJavaみたいにドメインを逆さにするのもなぁ
212:デフォルトの名無しさん
08/01/26 13:32:14
>エイリアスは .cpp のグローバルでのみ作るべし。
グローバルに alias 作るとヘッダが変わったときに突然コンパイルが通らなくなることあるよ。
213:デフォルトの名無しさん
08/01/26 13:35:49
前に関ったプロジェクトは常にフル指定?でメソッドを呼び出すべし
という規約があった
基底クラスのメソッドさえも
Hoge::Foo:Base:Dosomething();
多重継承を多用していたからという事情もあるんだけど
面倒だけど、安全ではある
214:デフォルトの名無しさん
08/01/26 13:46:38
その面倒なのがイヤだから using を使いたい、alias を使いたいってんだと思うが。
ぐるっと一周してきた感じだな。
215:デフォルトの名無しさん
08/01/26 14:07:49
グローバルにエイリアス量産するぐらいなら名前空間内で using 宣言した方がいいと思う・・・
216:デフォルトの名無しさん
08/01/26 18:53:06
しかしだな、エイリアスと別の名前空間が衝突することもあってだな・・・。
217:デフォルトの名無しさん
08/01/26 19:00:54
無限下降スパイラル
218:177
08/01/26 19:12:06
>>181
すいません、文字列クラスがcharacterDataではなくDatabaceでした。
>std::listを使って一本のリストを作って
listやmapを使うことも考えたんですが、リスト化した後のタイプの分岐判定のアルゴリズムが思いつかず断念しました。
なのでその辺のアルゴリズムのアドバイスも出してくれると助かります。
>コンパイルが通りそうなコード
コンパイルも通って動作確認もしてあるので正常に動作しているとは思います。
ただ、これだけ乱雑になると可読性に欠けてバグの温床になりそうなのでアイディアを聞きたいと思った次第です。
219:デフォルトの名無しさん
08/01/27 01:56:06
>>175
遅レスだけど、
そういう場合は鼻から悪魔がでますか?って聞けばいいよ。
220:デフォルトの名無しさん
08/01/27 11:37:37
//xxx.cpp
namespace
{
namespace ns = long::longlong::longlonglong::ns;
}
void F1()
{
ns::Foo();
}
221:デフォルトの名無しさん
08/01/27 13:21:55
template <typename T> //primary template
class Test {
public:
enum { Result = 1 };
};
template <typename T> //T const に対する partial specialization
class Test<T const> {
public:
enum { Result = 2 };
};
template<typename T>
void f(T t)
{
cout << Test<T>::Result << endl;
}
int main()
{
int i = 1;
f(i); // @ --> 1が表示される
int const j = 1;
f(j); // A --> 1が表示される
}
222:221
08/01/27 13:22:31
221です。続きです。
>>221 のtype functionについて疑問があります。
main関数内のAの呼び出しでは、渡している引数の型は確かに int const の
はずですが、結果はprimary templateが呼び出されます。Aでは T が
int const に deduction されて、T const に対する partial specialization
が呼ばれ、結果が2 になると思ったのですが、そうはなりませんでした。
明示的に f<int const>(j); とすれば 2 が表示されます。
何故 A の呼び出しで T が int const に deduction されないのでしょうか?
223:221
08/01/27 13:54:47
int const val;
のように変数valを定義した場合、valの型にconstは含まれるのでしょうか?
int const& ref;
の場合は、refの型は int const& となりconstは含まれますよね?
224:デフォルトの名無しさん
08/01/27 15:46:48
int const val; と const int val; は等価。
val の型に const は含まれる。
225:デフォルトの名無しさん
08/01/27 15:57:41
>>222
パラメータリストのconst修飾は関数の型としては無視される、
ということからだろうと思われる
たとえばvoid f(int);とvoid f(int const)の型は全く同一になる
f<int const>(j); とすれば 2 が表示されることに保証があるのか
俺は知らない
226:221
08/01/27 16:45:57
レスありがとうございます。
>>224
>int const val; と const int val; は等価。
それは知ってます。
やはり型の一部ですよね。
>>225
>たとえばvoid f(int);とvoid f(int const)の型は全く同一になる
value functionに関するそのルールは知っています。
このプログラムはvalue functionではなく、type functionなので
引数のdeductionの問題になると思います。f<int const>(j); は
明示的に型を指定しているのでpartial specializationが使用
されることは間違いないです。ただ、constが型の一部であるにも
関わらず、int const型のテンプレート引数である j を渡しても
specializationが使用されていないのが理解できません。
結果を見る限り、const修飾子が無視されてint引数として扱われてること
になりますが、これはテンプレートの標準における正しい仕様なのでしょ
うか?
VC++ 2008 と g++ v4 ともに同じ結果でした。
227:デフォルトの名無しさん
08/01/27 16:49:54
そもそも const int を int な引数の関数に渡せるしね。
規格でどうか知りたいなら、規格を読むのが一番だ。
228:221
08/01/27 17:09:22
>>227
それはvalue functionのパラメータ及び引数のルールであって、
テンプレートのtype parameterのdeductionはまた別の問題のよ
うに思います。もう少し規格を見てみます。
229:221
08/01/27 17:12:18
>>227
>>228は撤回します。
確かにそれが理由のような気がします。
そうすると、const int と T を比べると T が intに
deductionされるのも頷けます。
230:デフォルトの名無しさん
08/01/27 17:14:12
>>226
>partial specializationが使用 されることは間違いないです
ああそりゃそうか
>これはテンプレートの標準における正しい仕様なのでしょうか?
14.8.2 -3-にあった
231:デフォルトの名無しさん
08/01/27 17:17:06
手元にドラフトがあるのでそれで調べてみたが、14.8.2.1 p2 にそれらしきものが。
14.8.2.1 Deducing template arguments from a function call
If A is a cv-qualified type, the top level cv-qualifiers of A's type are ignored for type deduction.
232:デフォルトの名無しさん
08/01/27 17:18:11
あー、そっちかもしれん。>>230
233:デフォルトの名無しさん
08/01/27 17:19:04
>>226
type function とか value function とか、何の方言?
意味がわからない。
234:デフォルトの名無しさん
08/01/27 17:20:09
最新のドラフトを見ると怖いことが書いてあった
[ Note: f<int>(1) and f<const int>(1) call distinct functions even though both of the functions called have the
same function type. .end note ]
235:デフォルトの名無しさん
08/01/27 17:24:04
>>234
まあ明示的に指定する分には違っててもいいんじゃね?
236:221
08/01/27 17:34:09
>>230
>>231
>>232
>>233
>>234
>>235
みなさんレスありがとうございます。
>>231
まさにそれかと思います。同じことがJosuttisのC++ Templateにも
書いてありました。
こういう事情のようでです。
template<typename T> void f(T);
template<typename T> void g(T&);
int const ci = 123;
f(ci); // T is int
g(ci); // T is int const
すっきりしました。
237:デフォルトの名無しさん
08/01/27 17:40:02
int const& の const はトップレベルの const じゃないからそうなるわな。なるほど。
238:221
08/01/27 17:47:45
>>233
詳しいことは知りませんが、
現段階で標準で規定された言葉ではないと思います。
テンプレートの本に書かれていました。
value functionはいわゆる通常の関数を指します。
パラメータがtype、引数が値。
type functionとは、通常クラステンプレートで
実現されるものらしいです。
パラメータがテンプレートパラメータ、引数がtype。
struct Widget{};
Test<Widget>::Result;
>>221のTestクラステンプレートの場合、Widgetが引数で
type functionの戻り値がTest<Widget>::Resultと考え
ると通常の関数のように関数とみなせるというもだと
理解してます。
239:デフォルトの名無しさん
08/01/27 18:03:50
>>238
「テンプレートの本」ってどれだ?
普通に「関数」と「クラステンプレート」って言ったほうがいいと思うよ。
意味の違いを正しく表している呼び名だとは思えないからね。
後者は「(テンプレート)メタ関数」とか呼ばれるもののような気もするなぁ。
240:221
08/01/27 18:36:02
>>239
ここでいうtype functionとは
最近の言葉で表せばメタ関数でしょうね。
Boost::mplなどの最近のメタプログラミングで
使われていますが。
本はC++ Template The Complete Guideです。
著者は標準化委員会の現メンバーでもあり
信用できないものではないと思います。
通常の関数と対比して、コンパイル時に型を引数
とする”関数”という概念的に上手い言葉だと感じ
ているので自分はなるほどと思いました。
241:デフォルトの名無しさん
08/01/27 19:21:38
>>240
メタ関数でいいならそう言ったほうがいいでしょ。
わざわざ廃れた用語を使い続ける理由もない。
242:デフォルトの名無しさん
08/01/27 19:32:18
meta function == type function
別に正式な名前じゃないけど、
type functionってのはそこそこみる表現だから覚えておいてもいいと思うよ
243:デフォルトの名無しさん
08/01/27 23:07:12
>>241
別に廃れてるわけではないよ。
概念を表した言葉だから。
244:デフォルトの名無しさん
08/01/29 11:46:24
適当なオブジェクトのポインタが与えられたとき、そのオブジェクトのクラスがある特定の
名前と引数のタイプを持ったメンバ関数を持つときに限りその関数を呼んで処理したい
のですが、C++ で可能でしょうか?
あ、オブジェクトは必ずしも共通のスーパークラスを持たないとします。要はそういう
場合でも仮想関数的なことをしたいというか...
その特定のメソッドをもつ別クラスを作って、それを全てのオブジェクトで多重継承、
というのも考えているのですが、ちょっとダサいかな? と思って。あとソースのないクラス
では無理ですよね(今のところはソースのあるクラスだけでいいんですが)。
そもそもこんなことを考える事自体ナンセンス、と言われるとアレなんですがw
245:デフォルトの名無しさん
08/01/29 12:35:21
ポインタの型がテンプレート引数で与えられているならば、可能
246:デフォルトの名無しさん
08/01/29 12:41:29
>>245 嘘だろ。怪しいからソースを晒してください。
247:デフォルトの名無しさん
08/01/29 12:44:38
>>244おとなしく多重継承すべし。
248:デフォルトの名無しさん
08/01/29 12:52:14
>245が言いたいのは「コンパイル時にクラスが確定できる」場合だろ。
249:245
08/01/29 13:41:34
おかしいな。VC9だとhas_xxxが通らない。
自分で書いてみても、やはり通らない。
こんな風にSFINAEを使ってやればできるはずなんだけど。
struct BjarneStroustrup
{ void hage() ; } ;
struct Others
{ void fusafusa() ; } ;
template < typename T >
struct has_hage
{
struct Yes { char a[1] ; } ;
struct No { char a[2] ; } ;
template < typename Y > static Yes test(typename Y::hage const *) ;
template < typename Y > static No test(...) ;
static bool const value = ( sizeof( test<T>(0) ) == 1 ) ;
} ;
BOOST_STATIC_ASSERT(( has_hage<BjarneStroustrup>::value )) ;
BOOST_STATIC_ASSERT(( has_hage<Others>::value )) ;
250:245
08/01/29 13:42:58
最後の一行間違ってるけど気にしないで
251:デフォルトの名無しさん
08/01/29 14:42:17
template < typename Y > static Yes test(typename Y::hage const *) ;
はおかしくないか?
マッチしなかったぞ。
やるなら
template < typename Y > static Yes test(void (Y::*)(void));
か?
でも、これじゃあ関数名の一致の評価はムリだな。
何か仕組みが必要か。
252:デフォルトの名無しさん
08/01/29 14:42:50
struct BjarneStroustrup
{
void hage(){cout << "hage" << endl; }
};
struct Others
{
void fusafusa(){cout << "fusafusa" << endl;}
};
253:デフォルトの名無しさん
08/01/29 14:43:13
template <typename T>
struct has_hage
{
typedef char One;
typedef struct { char a[2]; } Two;
template < typename Y > static One test(void (Y::*)(void));
template < typename Y > static Two test(...);
enum { value = sizeof(test<T>(0)) == 1 };
} ;
template <typename T>
void func(T)
{
cout << "too bad" << endl;
}
template <>
void func(BjarneStroustrup* p)
{
p->hage();
}
template <typename T>
void call(T* t)
{
if(has_hage<T>::value)
func(t);
}
254:デフォルトの名無しさん
08/01/29 14:44:52
int main()
{
BjarneStroustrup b;
call(&b);
Others o;
call(&o);
}
255:デフォルトの名無しさん
08/01/29 15:02:09
struct BjarneStroustrup
{
typedef void HAGE;
void hage() const {cout << "hage" << endl; }
};
こういう風に typedef 定義して(擬似的な名前一致)
template < typename Y > static One test(typename Y::HAGE *);
じゃだめかいな。
256:デフォルトの名無しさん
08/01/29 15:34:33
これじゃあシグニチャが合わないか。
257:デフォルトの名無しさん
08/01/29 15:45:03
ちょっと変更
struct HAGE{};
struct BjarneStroustrup
{
template <typename T>
void hage();
template <>
void hage<HAGE>() {cout << "hage" << endl; }
};
template <typename T>
struct has_hage
{
・・・・・
template < typename Y > static Two test(...);
・・・・・
} ;
template <>
void func(BjarneStroustrup* p)
{
p->hage<HAGE>();
}
258:デフォルトの名無しさん
08/01/29 15:46:00
こっちだった。
template <typename T>
struct has_hage
{
・・・・
template < typename Y > static One test(void (Y::*)(HAGE));
・・・・
} ;
259:デフォルトの名無しさん
08/01/29 17:12:00
このスレって頭悪い奴多いね
260:デフォルトの名無しさん
08/01/29 17:20:47
そもそもプログラミングしてる時点でアレだしな
261:デフォルトの名無しさん
08/01/29 17:55:27
ググったらこんなのが出てきた。
URLリンク(www.gamedev.net)
これを基に少し改造してみた。BjarneStroustrupとOthersは>>249の定義を使用。
#include <iostream>
#include <boost/mpl/bool.hpp>
//#include <boost/type_traits.hpp>
struct SFINAE {
typedef char one;
typedef struct { char c[2]; } two;
};
template<typename T>
class has_hage_impl {
template<void (T::*)()> struct Wrap {};
template<typename U>
static SFINAE::one Determine(Wrap<&U::Hage>* w);
template<typename U>
static SFINAE::two Determine(...);
public:
static const bool value = sizeof(Determine<T>(0)) == sizeof(SFINAE::one);
};
template<typename T>
struct has_hage : boost::mpl::bool_<has_hage_impl<T>::value> {};
//boost::integral_constant<bool, has_hage_impl<T>::value>も可
int main() {
std::cout << std::boolalpha
<< has_hage<BjarneStroustrup>::value << '\n'
<< has_hage<Others>::value << std::endl;
}
262:デフォルトの名無しさん
08/01/29 18:26:26
>>259
ほんとだね
263:デフォルトの名無しさん
08/01/29 18:27:59
>>259
具体的な解決策はありますか?
264:デフォルトの名無しさん
08/01/29 18:31:49
クラステンプレートのテンプレイート引数をバインドしたいと思っています。
考えたのは
template <class T1, class T2>
class A {...};
template <class T1>
class AInt {
public:
typedef A<T1, int> type;
};
このような方法ですが、AInt<Hoge>::typeとしないといけないところに不満が残ります。
typedef A<T1, int> template <class T1> AInt;
こんな感じで完全にバインドしてしまう方法はないでしょうか?
265:デフォルトの名無しさん
08/01/29 18:33:14
0,1,2,3,4
から
2個取り出すときの全組み合わせ
3個
4個
5個(は1通りだけど)
を文字列(stringでもcharでも)として吐き出すプログラムを
書きたいんですがアイディアだけでもいただけないでしょうか?
266:デフォルトの名無しさん
08/01/29 18:41:20
>>265
それなんて宿題?
267:デフォルトの名無しさん
08/01/29 18:44:37
>>264
今のC++にはない。0xに乞うご期待。
その方法が嫌なら、使える場合が限られるけど継承するか、
template <class T1>
class AInt : public A<T1, int> {};
あとはプリプロセッサマクロで何とかするか。
268:デフォルトの名無しさん
08/01/29 18:47:21
や、宿題じゃないんですが自分でプログラムかいててハタと迷ったので・・
スレチならすいません
269:デフォルトの名無しさん
08/01/29 19:03:09
>>265
なにが固定でなにが引数になるか書いてくれないと答えようがないぜ。
270:264
08/01/29 19:03:55
>>267
そうなんですか。
ありがとうございました。
271:268
08/01/29 19:03:59
すいませんネットから拾ったプログラムを改変したら多分出来ました。
#include <stdio.h>
int main(int argc ,char *argv[]){
int a=0,b=0,c=0,d=0;
for (a=0;a<=4;a++){
for (b=0;b<=4;b++){if(b==a || a>b)continue;
for (c=0;c<=4;c++){if(c==a || c==b || b > c)continue;
for (d=0;d<=4;d++){ if(d==a||d==b||d==c||c>d)continue;
cout <<a<<b<<c<<endl;
}
}
}
}
return 0;
}
272:デフォルトの名無しさん
08/01/29 19:06:23
スレ違いだな。
ここは見ての通り、C++の規格書を暗記している奴が、
C++の文法で、Bjarne Stroustrupがハゲているかどうか、
コンパイル時に判定するスレだ。
ソースコードが実用的かどうかは、どうでもいい奴らなんだよ。
重要なのは規格違反かどうかということだけだ。
まあ、大方のスレ住人もハゲてるんだけどな。
273:デフォルトの名無しさん
08/01/29 19:07:30
ゆとり教育のカリキュラムには順列・組み合わせとかないの?
274:268
08/01/29 19:08:50
>272
thx
俺はケツ毛までフッサフサです。
275:デフォルトの名無しさん
08/01/29 19:20:28
>>267
Template aliases for C++
URLリンク(www.open-std.org)
のこと?
276:デフォルトの名無しさん
08/01/29 19:43:27
>>244
テンプレートじゃ無理なんか?
277:245
08/01/29 20:05:40
>>261
お、それだとVC9でもBOOST_STATIC_ASSERTが通った。
でもおかしいな、確か昔、C++ Templatesで読んで、実際に自分で試してみて、
スゲーと感動した記憶があるんだけど。
たしかVC7だったかな。
あとBoostのhas_xxxって、これ関数じゃないんだね。知らなかった。
278:デフォルトの名無しさん
08/01/29 20:17:41
VC++6.0で開発してます。
CHttpFile::SendRequestEx() にて、
CInternetException以外の例外が発生するケースが稀にあるようなんですが、原因が特定できず悩んでいます。
そもそもCInternetException* の例外以外がスローされることってあるんでしょうか?
どっかのサイトでは、CFileExceptionもスローされると書いてあったんですが・・・。
どなたか、このような経験が方いらっしゃいましたら御教授下さい。
279:デフォルトの名無しさん
08/01/29 20:20:17
スレ違い。
280:デフォルトの名無しさん
08/01/29 20:24:40
>>277
で、結局、>>244 のやりたいことは可能なのか?
281:デフォルトの名無しさん
08/01/29 20:26:51
オナニーレスばっかりだな
282:デフォルトの名無しさん
08/01/29 20:32:21
しこしこ
283:デフォルトの名無しさん
08/01/29 20:35:25
ズルムケ
284:デフォルトの名無しさん
08/01/29 20:35:45
それは鈴木ムネオの秘書だろ
285:デフォルトの名無しさん
08/01/29 20:46:26
>>280
さー?
>>244が静的な多様性でいいのかどうか分からないからなんとも。
しかし動的な多様性がほしいとすると、引っかかることも。
「ポインタで与えられる」、しかし共通のベースクラスがあるわけではないってことは、void *型で渡すんだろうか。
それだと特定のメンバ関数云々よりも、そもそもオブジェクトのクラスの型は何だってことになるし。
動的な多様性がほしい、
しかし、既存のコードはいじりたくないので、共通のベースクラスに純粋仮想関数は使えないというのなら、
例えばBoost.Anyに使われているType Erasureのテクニックが使えるかもしれない。
あの単純すぎるテクニックを使えば、かなり変態的なことができる。
286:デフォルトの名無しさん
08/01/29 20:51:54
>>285
変態ということはわかった
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
5011日前に更新/95 KB
担当:undef