08/01/23 22:53:45
ただし、テンプレート引数が参照な時だけだっけ?
&& を素で書くと右辺値参照だったはず。
128:デフォルトの名無しさん
08/01/23 23:52:55
>>126
>>127
そうですか。テンプレートパラメータが既に参照の場合、
参照引数を渡すとT& &となりエラーとなるため、これを
回避することだけを目的としてるのかもしれないですね。
type functionを書くのも面倒なので是非改定
してもらいたいです。もしかすると今でもBoostでは便利
なものがあるかもしれませんが。
右辺値参照はC++03では認められていなくて、C++0xでは
正当になる予定ですよね?
129:デフォルトの名無しさん
08/01/24 00:15:13
あれ? 離して書くと大丈夫だったかもしれん。
うろ覚えだからドラフト読んでくり。
130:デフォルトの名無しさん
08/01/24 00:24:22
>>129
確認してみます。
131:デフォルトの名無しさん
08/01/24 00:34:53
参照への参照なんて使うことあるの?
132:デフォルトの名無しさん
08/01/24 00:47:44
>>131
テンプレートでこねこねしていると、うっかり参照への参照という型が生まれることがある。
そんなもの、現状ではコンパイルエラーだが、125に書いてある通り0xだと、
Tへの参照への参照型は、単にTへの参照型として扱われるようになる。
133:デフォルトの名無しさん
08/01/24 01:00:12
& & -> &
& && -> &
&& & -> &
&& && -> &&
134:デフォルトの名無しさん
08/01/24 01:01:32
>>132
thx うっかり、ってことは積極的に作るものじゃないって事でOK?
135:デフォルトの名無しさん
08/01/24 01:19:02
URLリンク(www.open-std.org)
URLリンク(www.open-std.org)
このあたりかな。あまり理解できなかった。
改定理由はテンプレートパラメータの問題としてだけでなく、
右辺値参照との絡みもあるみたいだ。かな?
136:デフォルトの名無しさん
08/01/24 01:35:59
&&& はwell-formedなのか気になる
137:デフォルトの名無しさん
08/01/24 01:39:01
ill
138:デフォルトの名無しさん
08/01/24 01:58:45
>>135
template<typename T1, typename T2, typename T3>
void f(T!&& x, T2&& y, T3&& y);
例えば、こんな関数にboost::refで一部の引数だけ左辺値参照にすることができる。
そんなことできて何が嬉しいって、例えばBoost.BindやBoost.Lambdaの関数呼出。
これは& &→&というより、&& &→&の説明になっているけど。
139:デフォルトの名無しさん
08/01/24 13:40:10
別に boost::ref などを使わなくても,
普通に左辺値を引数にすれば左辺値参照として bind されるのでは?
140:デフォルトの名無しさん
08/01/25 01:22:36
くわしく
141:デフォルトの名無しさん
08/01/25 02:32:53
以下抜粋
1. lvalues can bind to an rvalue reference.
2.
struct A {};
void h(const A&);
void h(A&&);
void g(const A&);
void g(A&&);
void f(A&& a)
{
g(a); // calls g(const A&)
h(a); // calls h(const A&)
}
Although an rvalue can bind to the "a" parameter of f(), once bound, a is now treated as an lvalue.
>>139の言うとおりのような気がする。
142:デフォルトの名無しさん
08/01/25 13:02:29
そもそもboost::refをなくすための&&ですやん
143:デフォルトの名無しさん
08/01/25 13:17:13
いや、&&はmove semanticsのためでしょ。
boost::refはoutパラメータとして使うためにあるんだと思ってる。
144:139
08/01/25 13:52:28
以下 C++0x の話で現行の言語規格とは一切関係ないです.スレ違いですいません.
>>141
あ,いえ,自分が>>139で指摘したかったのはたとえば
template<typename T>
void f(T &&x);
があったときに, f を左辺値で呼び出すと T が左辺値参照型で specialize されて
f のパラメタの型が左辺値参照型になる,つまり
int i;
f(i); // T = int & として f が specialization される.
// 結果 f のパラメタの型が & && -> & の decay を受けて int & と同等になる
f(42); // T = int として f が specialization される.
// 結果 f のパラメタの型が右辺値参照型 int && になる
ということです.これによって f の引数が非 const 左辺値でも const 左辺値でも右辺値でも
問題なく受けられるようになるということを指摘したかったんです.
で,上記の仕様 (引数が左辺値か右辺値かで
テンプレートパラメタ T が参照型かそうでないかの違いが生じる) から,
f の実装内部において f が左辺値で呼ばれたのか右辺値で呼ばれたのかの識別も可能となります.
この 右辺値参照・参照型の decay ルール・関数テンプレートにおける引数推論規則 の組み合わせで
the forwarding problem が完全に解けるというのが現在の提案の骨子だったかと思います.
145:139
08/01/25 13:54:25
あと,実際には>>141さんが指摘しているように
名前が付いた右辺値参照は左辺値として扱われるので,
右辺値として渡された f の引数を f の内部で引き続き右辺値として扱うには
明示的に右辺値参照に変換してやらないといけないです.
で,このために std::forward という補助的な関数テンプレートも提案されています.
template<typename T>
T &&forward(typename identity<T>::type &&x){return x;}
template<typename T>
void f(T &&x)
{
g(forward<T>(x)); // f が右辺値で呼ばれている場合, T が非参照型になっているので
// forward の戻り値型が右辺値参照型になり,右辺値として g に渡される.
// f が左辺値で呼ばれている場合, T が参照型になっているので
// forward の戻り値型が左辺値参照型になり,左辺値として g に渡される.
}
146:デフォルトの名無しさん
08/01/25 15:50:00
>>143
boost::refについて、これ嘘だった。
147:デフォルトの名無しさん
08/01/25 16:25:54
まったく話についてけないんだが。
何が左辺値で何が右辺値なんだかもうわけわからん
右辺値で呼ぶってどういうこと?
148:デフォルトの名無しさん
08/01/25 16:44:11
template <class T>
struct identity
{
typedef T type;
};
template <class T>
inline
T&&
forward(typename identity<T>::type&& t)
{
return t;
}
149:デフォルトの名無しさん
08/01/25 16:49:21
>>144
f(i); // T = int & として f が specialization される.
T が int & にdeductionされるのって、パラメータが右辺値参照
のときのみのルールですよね?
150:デフォルトの名無しさん
08/01/25 16:52:33
Let us first consider the rvalue reference type, T &&, in more detail in
the context of the C++ type system. What if T is itself a reference
type? Template libraries have been known to create reference to
reference types via typedefs or type manipulations. According to the
proposed resolution to Core Defect Report 106 , ordinary references obey
the equality T cv1 & cv2 & == T cv12 &, where cv12 is the union of cv1
and cv2. A similar reasoning can be applied to collapse two rvalue
references into one: T cv1 && cv2 && == T cv12 &&.
こいう文書で出てくるcv1やcv2やcv12の数字は何を意味してるんですか?
151:デフォルトの名無しさん
08/01/25 17:25:21
区別するため便宜的に番号を振っているだけ。
例えばcv1 = const, cv2 = volatileなら、
vc12 = const volatileだよという話をしたいがためのもの。
152:デフォルトの名無しさん
08/01/25 18:57:19
>>151
なるほど。unionは合成の意味ですね。てっきりキーワードもunionかと
思ってしまいました。
153:デフォルトの名無しさん
08/01/25 19:59:08
すいません.>>145で示した forward の定義は
正確には>>148さんの書いたとおりです.
>>147
>何が左辺値で何が右辺値なんだかもうわけわからん
戻り値の型が左辺値参照型でない関数の呼び出し構文(の結果)が右辺値で,
それ以外は全て左辺値,という理解である程度通用するかと思います.
>>149
全部把握しているわけではないので推測になりますが,恐らくそうだと思います.
後方互換性の観点から考えても,
パラメタが右辺値参照型以外の場合は従来どおりの deduction になるかと.
154:デフォルトの名無しさん
08/01/25 21:19:46
システムの構造体の定義をXML形式で出力したいんだけど、上手い方法があったら教えてださい。
ある構造体は中にも構造体を保持していて、その構造体は別ファイルで定義してるとか、
ifdefやら二重に定義されてるマクロやらで手動でやろうとするともうワケワカメです
155:デフォルトの名無しさん
08/01/25 21:46:14
>>153
The next step is to modify the argument deduction to retain information
about the "rvalueness" of the argument: when deducing against a template
parameter of the form A1 &&, deduce A1 as a reference type when the
argument is an lvalue, and a non-reference type otherwise. According to
our T cv1 & cv2 && == T cv12 & rule, this effectively means that the
type of the argument will be A1 & when the argument is an lvalue, and A1
&& otherwise.
どうやら右辺値参照パラメータに対する特別なdeduction ruleみたいですね。
156:デフォルトの名無しさん
08/01/25 23:08:28
独自ネームスペースを持つ外部ライブラリを幾つか利用して大きなプログラムを書くようになったら
#include "hoge1.h"
……
#include "hogeN.h"
#include "mylib1.h"
……
#include "mylibN.h"
#include <lib1.h>
……
#include <libN.h>
namespace current_namespace {
using ns1::hoge1;
……
using ns1::hogeN;
……
using nsN::hoge1;
……
using nsN::hogeN;
……
な感じで各ファイルの先頭が埋め尽くされるようになりました。
皆さん、どのように解決しているのでしょうか?
157:デフォルトの名無しさん
08/01/25 23:51:26
全てのヘッダを include するヘッダを作って、ソースコードの先頭で
#include "all.h"
とする。
158:デフォルトの名無しさん
08/01/25 23:53:59
リコンパイルで半泣きコースだな
159:デフォルトの名無しさん
08/01/26 00:11:45
リコンパイルで半泣きといえば、いろんな本で冗長インクルードガードが嫌われてるのは何でよ?
VC++2005の #pragma once を使ってる場合ですら200ファイルほどのプロジェクトでリビルド時間が半減したんだけど。
160:デフォルトの名無しさん
08/01/26 00:27:07
>>157
using もヘッダん中ですんのか?
161:デフォルトの名無しさん
08/01/26 00:29:14
precompiled headerになるようにしときゃいいだろ。
162:デフォルトの名無しさん
08/01/26 00:48:04
>>159
よく分からんけど、
#pragma once
よりも、
#ifndef XXXXXXX
#define XXXXXXX
////
#endif
の方がビルド時間が短くなるの?
163:くお
08/01/26 00:49:00
c++でエクセル用のアドインを作るやり方を教えてください。
よろしくお願いします。
164:デフォルトの名無しさん
08/01/26 00:59:44
>>162
#ifndef XXXXXXX
#define XXXXXXX
#include "myhoge.h"
#endif XXXXXXX
とやって include 行を読み飛ばす方法。
myhoge.h にアクセスする必要がない、展開後のファイルサイズが小さくなる、等の理由でビルド時間が短くなることが多い。
165:デフォルトの名無しさん
08/01/26 01:00:16
くおーっ!
166:デフォルトの名無しさん
08/01/26 01:01:52
>>157
all.h に含まれるヘッダのどれか一つでも更新されると all.h を含むファイルが全てコンパイルされる罠。
all.h をプリコンパイルヘッダにしたところで防げません。
167:デフォルトの名無しさん
08/01/26 01:08:25
批判もいいけど先に解決策を示そうぜ。
168:デフォルトの名無しさん
08/01/26 01:11:42
>>164
なるほど。それだとすると、159の
>リコンパイルで半泣きといえば、いろんな本で冗長インクルードガードが嫌われてるのは何でよ?
の理由は、ヘッダファイル使用時にやることが増えるから。かな?
いや、そっちの方が早いってのなら、合理的な理由じゃないとは思うけど
多分159に対する答えは、そんなところだと思う。
169:デフォルトの名無しさん
08/01/26 01:12:55
つURLリンク(en.wikipedia.org)
170:デフォルトの名無しさん
08/01/26 01:39:56
初歩的な質問で申し訳ないのですが、ヘッダファイルの中で行う以下のような
0クリアは問題ないですか?sizeof(this)は正しく計算されます?
class HOGE
{
int a,b,c;
char str[128];
void init(void)
{
memset( this, 0, sizeof(this) );
};
};
171:デフォルトの名無しさん
08/01/26 01:41:18
>>170
やってみりゃいいじゃん
172:デフォルトの名無しさん
08/01/26 01:44:07
いえ、できれば構文的に正しいのか知りたいのですが…
テストのクラスで成功しても、他のクラスでは失敗するかもしれないので。
173:デフォルトの名無しさん
08/01/26 02:03:15
>>172
コンパイルが通れば、構文的には正しい。
というのは置いといて、
メンバ変数をクリアしたければ、sizeof(*this)とすべき。
そして重要なのは、その方法が使えるのはPOD型だけ。
例えばHOGEに仮想関数を追加すると、動かなくなる。
174:デフォルトの名無しさん
08/01/26 02:03:42
構文って意味分かってんのかいな…。
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); // ② --> 1が表示される
}
222:221
08/01/27 13:22:31
221です。続きです。
>>221 のtype functionについて疑問があります。
main関数内の②の呼び出しでは、渡している引数の型は確かに int const の
はずですが、結果はprimary templateが呼び出されます。②では T が
int const に deduction されて、T const に対する partial specialization
が呼ばれ、結果が2 になると思ったのですが、そうはなりませんでした。
明示的に f<int const>(j); とすれば 2 が表示されます。
何故 ② の呼び出しで 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
便利のようでそうでもないかな。変な副作用はなさそうだから気にしないでおこう。