C++相談室 part60at TECH
C++相談室 part60 - 暇つぶし2ch2:デフォルトの名無しさん
08/01/11 18:44:27
■基本■
[C++ FAQ]
 URLリンク(www.parashift.com)
 URLリンク(www.bohyoh.com) (日本語)
  Cとその仕様を比較しながらの解説なので分かりやすい。
  ***** 質問の前に必ずこの二つに目を通してください *****
[C/C++ リファレンス]
 URLリンク(www.cppreference.com) (英語)
 URLリンク(www.cppll.jp) (↑の日本語訳だけど最新は反映しない)
[禿 Stroustrup]
 URLリンク(public.research.att.com)
[C++ International Standard]
 URLリンク(www.iso.org)
[JTC1/SC22/WG21 - C++]
 URLリンク(www.open-std.org)
  ここから規格の最新(2003より新しい)ドラフトがダウンロードできる。
[JIS X3014]
 URLリンク(www.jisc.go.jp)
  ISO規格の日本語訳。JIS X 3014:2003はISO/IEC 14882:2003 (E)に対応。

3:デフォルトの名無しさん
08/01/11 18:44:42
■Books(Templateまわり)■
Effective STL
 URLリンク(www.amazon.com)
 URLリンク(www.amazon.co.jp) (翻訳)
Modern C++ Design
 URLリンク(www.amazon.com)
 URLリンク(www.amazon.co.jp) (翻訳)
C++ Templates
 URLリンク(www.amazon.com)
C++ Template Metaprogramming
 URLリンク(www.amazon.com)

4:デフォルトの名無しさん
08/01/11 18:44:58
■Libraries■
[Boost]
 Boost URLリンク(www.boost.org)
 (日本語) URLリンク(www.kmonos.net)
 (日本語) URLリンク(shinh.skr.jp)
[標準ライブラリ]
 SGI-STL URLリンク(www.sgi.com)
 STLport URLリンク(stlport.sourceforge.net)
 GNU libstdc++ URLリンク(gcc.gnu.org)
 Apache STDCXX URLリンク(incubator.apache.org)
 STLFilt URLリンク(www.bdsoft.com)
 (日本語) URLリンク(www005.upp.so-net.ne.jp)
 (日本語) URLリンク(www.wakhok.ac.jp)
[Loki]
 URLリンク(sourceforge.net)
 LokiPort-MSVC6sp5 URLリンク(fara.cs.uni-potsdam.de)

5:デフォルトの名無しさん
08/01/11 18:45:19
STLつかうと一気に実行ファイルサイズが10倍に?!

環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない

すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。

C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?

#include <stdafx.h>
後死ね。

言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。


6:デフォルトの名無しさん
08/01/11 18:45:37
前スレ

C++相談室 part59
スレリンク(tech板)

7:デフォルトの名無しさん
08/01/11 19:00:39
復活か?

8:デフォルトの名無しさん
08/01/11 19:10:02
Prototype パターンに関する質問
派生させた、インスタンスの消滅(delete)は何処でやったらいい?
基底のデスクトラクタは、Effective C++ 新訂3版、宜しく
virtualで宣言してるんだけど?


9:デフォルトの名無しさん
08/01/11 19:12:26
C++ Primer 4/E 買った奴いる?
内容はどうだった?

10:デフォルトの名無しさん
08/01/11 19:15:00
>>8
俺はstd::auto_ptrに突っ込んでいるが。

11:デフォルトの名無しさん
08/01/11 19:53:48
>>8です
とりあえず
std::auto_ptr
boost::shared_ptr
は、なしで宜しくオナガイシマス

12:デフォルトの名無しさん
08/01/11 20:02:58
同等のクラスを作れ

13:デフォルトの名無しさん
08/01/11 20:14:00
>>12
kuwasiku

14:デフォルトの名無しさん
08/01/11 20:18:29
おもっくそ真面目に作りたきゃ Modern C++ Design でも読めばいいが、
適当でいいなら適当なソース読め。

15:デフォルトの名無しさん
08/01/11 20:20:26
>>Modern C++ Designは持ってるが、読破できん
>>適当でいいなら適当なソース読め。
どこにある?


16:デフォルトの名無しさん
08/01/11 20:41:09
boostなら落としてこい。
auto_ptrならコンパイラが持ってるかも知れん。検索しろ。
開発環境書かなきゃディレクトリなんてわかるか。

17:デフォルトの名無しさん
08/01/11 20:50:05
>>11
std::tr1::shared_ptrという抜け穴w

18:デフォルトの名無しさん
08/01/11 20:54:22
Loki のやつを使うという手も

19:デフォルトの名無しさん
08/01/11 21:08:13
>>8だが
LokiはModern C++ Designに載ってるライブラリだろうが
なもん判るか、ぼけ
ってゆうか、予想はしてたが、Prototype パターンで、派生させた、
インスタンスを消滅させるのって、やっかいなんだな

20:デフォルトの名無しさん
08/01/11 21:15:18
読めと言ってる訳じゃねー

21:デフォルトの名無しさん
08/01/11 21:28:03
最大50桁の数字を2つ入力して
その和と積と差を求めるプログラムを作りたいんだけど、
50桁も入力できない!!!
20桁もできない

どうすれば入力できますか?

22:デフォルトの名無しさん
08/01/11 21:29:37
>>19
べつにPrototypeに限らん。
生成パターンで生成させたオブジェクトは皆同じ。
元々JavaとかC#に向いた手法だよな。

23:デフォルトの名無しさん
08/01/11 21:30:31
多倍長演算でググれ

24:デフォルトの名無しさん
08/01/11 21:32:05
>>21
入力を文字列として読み取り、ひと桁ずつを配列に入れる。
あとはお前が筆算をやる要領でひと桁ずつ下の桁から加算する。
10を超えたら次の桁(=次の配列)に桁上げする。

単純だけど、こんなんでも一応実現できる。


25:デフォルトの名無しさん
08/01/11 21:41:12
>>21
マルチ
今宿題スレに行ってるな

26:デフォルトの名無しさん
08/01/11 21:48:00
>>19
>>22
個人的な意見だが、ポインタ使って、ヒープにメモリ確保するのって
後始末が煩雑だから、嫌なんだよね、静的にインスタンスが、作れないものかな・・・



27:デフォルトの名無しさん
08/01/11 22:16:52
>>25
宿題スレ行きました
出来れば助けてください!笑

>>29
ありがとうございます!!(ノ_・。)

28:デフォルトの名無しさん
08/01/11 22:34:59
↑上の
29じゃなくて
>>24
のまちがいでした。。
あと、できればプログラム詳しく教えてほしいんですが(ノ_・。)
配列にいれて足していくってどうやればいいですか???

>>23
ぐぐります!!

29:デフォルトの名無しさん
08/01/11 23:12:53
>>28
マルチしてるのでどっちか取り下げないか?
助けてやろうにもどっちで助ければいい?

30:デフォルトの名無しさん
08/01/11 23:20:49
じゃあ向こうのスレでお願いします!!

31:デフォルトの名無しさん
08/01/11 23:23:23
マルチごめんなさい(ノ_・。)

32:デフォルトの名無しさん
08/01/12 11:05:00
More Effective C++ 新訂3版のテクニックという章に
class NLComponent
{
  virtual NLComponent * clone() const = 0 ; // クローンメソッド
};
基底クラスに、純仮想関数を宣言して、派生クラスでインスタンスを生成する方法が
載っているんだけど、一例で、ディスク上に保存されている、オブジェクトを
std::istream strを引数にとるコンストラクタで渡してやってるんだけど
これって、なんかおかしい気がする、理由は、コンストラクタで例外が起きたらどうなるんだ?
どう思うよモマイラ

33:デフォルトの名無しさん
08/01/12 11:15:58
>>32より
32の質問は却下します、スマン

34:デフォルトの名無しさん
08/01/12 17:50:36
>>33
おいおい、自分で書いておいて却下するなよ。

35:デフォルトの名無しさん
08/01/13 23:53:36
VC++ 2005を使っています。
テキストファイルから文字列を読み込んでいるのですが、CStdioFileなどを使った読み込みですと、1行ずつ読み込むしかありません。
これを、1行ではなく指定の区切り文字まで読み込む、というのをやりたいのです。

具体的に言うと、「。」がくるまで読み込みをやりたいと思っています。

今日は晴れです。明日も晴れです。

という文章を読み込む場合、最初の読み込み時では
今日は晴れです。
が読み込まれ、次の読み込みで
明日も晴れです。
が読み込まれるようにしたいと考えています。

何か標準のライブラリでこのようなものはないでしょうか? よろしくお願いします。

36:デフォルトの名無しさん
08/01/14 00:14:40
1文字ずつ読み込んで、望みの区切り文字列が現れたところで止める。

37:デフォルトの名無しさん
08/01/14 00:35:49
>>35
getline(basic_istreamのメンバもグローバル関数のほうも)では、
\nに代わって区切る文字を指定できる。

ただし、元が改行文字を取り除く仕様なので、
当然指定した区切り文字は削除される。

std::wifstream is("hoge.txt");
is.imbue(std::locale("japanese"));

std::wstring s1, s2;

std::getline(is, s1, L'。');
std::getline(is, s2, L'。');

//s1 == L"今日は晴れです"
//s2 == L"明日も晴れです"

38:35
08/01/14 01:58:54
>>37
どうも、ありがとうございます。それを使ってみたいと思います。

39:デフォルトの名無しさん
08/01/14 21:44:28
Emacs にも Visual C++ の IntelliSense のような
入力支援機能を実現する Emacs Lisp プログラムが
用意されているのでしょうか?

単純なキーワード色づけは今も使っているのですが,
もっと詳細な情報を得たいと思っています.

40:デフォルトの名無しさん
08/01/14 23:51:44
C++及びオブジェクト指向初学者です(C++入門本一読程度) 。いくつかの
クラスオブジェクト(CObjxx)を任意数包含する クラス(CTestxx)を複数生成
したいと考えています。
class CObjA {...}; // 既存クラス(修正不可)
・・・
class CObjD {...}; // 既存クラス(修正不可)
class CTestA {
private:
CObjA m_objA;
CObjB m_objB;
};
class CTestB {
private:
CObjB m_objB;
CObjC m_objC;
};
・・・
class CTestF {
private:
CObjA m_objA;
CObjC m_objC;
};
int main()
{
CTestA testA;
・・・
}
現在、このような実装で検討していますが、この方法だと各CTestxx毎に
CObjxxに対するアクセサを 用意してあげる必要があり、かつ似たような
巨大なクラスCTestxxが出来上がってしまい、 スマートな実装ではない気が
しています。。。 上記のようなケースは どのように実装するのが適切なのでしょうか。
ご教授をお願いします。

41:デフォルトの名無しさん
08/01/14 23:51:44
んー、それは言語系スレじゃなくてツール系スレに行くべきかな。

42:デフォルトの名無しさん
08/01/14 23:56:00
>>41>>39へのレス

>>40
抽象度が高すぎてなんともいえないな…。
CTestXXはラッパークラスなんかね?
それとも唯のコンテナか…エスパーに任せる。

43:デフォルトの名無しさん
08/01/14 23:58:18
>>40
各Obj毎のアクセサクラス作って多重継承してみたら?
class CObjAAccessors {
public: objA用アクセサ;
protected: CObjA m_objA;
};
class CObjBAccessors {
public: objB用アクセサ;
protected CObjB m_objB;
};
class CObjCAccessors {
public: objC用アクセサ;
protected: CObjC m_objC;
};
class CTestA: public CObjAAccessors, public CObjBAccessors{};
class CTestB: public CObjBAccessors, public CObjCAccessors{};
...
class CTestF: public CObjAAccessors, public CObjCAccessors{};

44:デフォルトの名無しさん
08/01/15 00:02:24
>>39
ある。無論標準装備ではない。

45:デフォルトの名無しさん
08/01/15 00:25:29
ある基底クラスと派生クラス群があって
格派生クラス群は固有タイプのパラメータ(intやdouble[2]とか)を持っているとする

開始関数Begin()を呼ぶ前にそれぞれ独自のパラメータを
SetParameter(ParameterType[], int paramSize)で渡したい

たとえば
Derive1::PARAM param1[] = {3}; // int
Derive2::PARAM param2[] = {0.9, 0.8}; // double[2]
Derive1->SetParameter(param1, 1);
Derive2->SetParameter(param2, 2);
Derive1->Begin();
Derive2->Begin();

という感じ

現在これをテンプレートで実現してて

(続く)

46:デフォルトの名無しさん
08/01/15 00:29:32
class Base{
void** param_;
virtual bool Begin() = 0;
public:
Base() : param_(NULL){}
template <class T> bool CreateParameter(T[], int);
template <class T> void DeleteParameter();
template <class T> T GetParameter(int) const;
};
template <class T> bool Base::CreateParameter(T param[], int n) {
if(param_) return false;
param_ = reinterpret_cast<void**>(new T*[n]);
for(int i=0; i<n; i++) param_[i] = new T(param[i]);
return true;
}
template <class T> void Base::DeleteParameter(){
delete[] reinterpret_cast<T**>(param_);
param_ = NULL;
}
template <class T> T Base::GetParameter(int n) const{
return *(static_cast<T*>(param_[n]));
}

(続く)

47:40
08/01/15 00:55:05
早々のご回答ありがとうございます。

>>42
初学ゆえ説明足らずで申し訳ありません。
CTestxxはCObjxxの機能を有するという形で実装したいと考えています。
CObjxxとCTestxxの間にラッパクラスを挟むべきか、それともよりよい
実装方法があるのか、そもそもCObjxxは包含すべきものなのか、
というところを悩んでいます。なんかうまく説明できなくてすみません。。。

>>43
なるほど。この方法だとCTestxxはCObjxxの機能を有しつつ、必要な部分だけを
公開できそうです。貴重なご意見ありがとうございます。

48:デフォルトの名無しさん
08/01/15 02:16:35
gccでSJISファイルのコンパイルでうまくいかないので、ご教授いただけたらと思います。

> cat a.c
#include "stdio.h"
#define AAA(a) BBB(#a)

void BBB(char *str) {
printf("%s\n", str);
}

int main() {
AAA(あ"い");
BBB("あ\"い\"");
}

> gcc --input-charset=cp932 --exec-charset=cp932 a.c
> a.out
あ"磚
あ"い"

AAAの方とBBBの方で両方同じ結果が得られそうなのですが、
AAAの方でうまくいっていないのを解決したいと思っています。

ここでは標準出力していますが、内部文字コードはSJISのまま解決したいと思っています。
よろしくお願いいたします。

49:デフォルトの名無しさん
08/01/15 08:34:52
>>41 >>44
THX
ちょ,名前だけでもw
といってもすれ違いの気もするから Emacs スレに行きます

50:デフォルトの名無しさん
08/01/15 22:27:52
>>48
--input-charsetじゃなくて-finput-charsetだった希ガス
つーかすれ違い

51:48
08/01/15 23:53:54
>>50
ありがとうございます。
--input-charsetは-finput-charに展開されていたと思うので確か同じことだと思います。
GCCスレに同じ質問投げてきます。失礼しました。

52:デフォルトの名無しさん
08/01/16 16:52:57
下記のようにboost::arrayで代入演算子が定義されている型Tの2次元配列を
で作りたいのですが、BOOST_PPとtemlateで一般化できないでしょうか?
自分でも考えたのですが脳みそが沸騰しそうでした。

struct Row : public boost::array<T, XSIZE>
{
Row(T x0, T x1,..., T xXSIZE_minus1) : boost::array<T, XSIZE>()
{at(0) = x00; at(1) = x01;... at(XSIZE - 1) = xXSIZE_minus1;
};

const boost::array<Row, YSIZE> plane = {
Row(xx, xx, ... , xx),
...
Row(xx, xx, ... , xx)
};

53:52
08/01/16 16:56:53
追記
const boost::array<Row, YSIZE> plane
は手書きで初期化します。一般化したいのはRowだけです

54:デフォルトの名無しさん
08/01/17 16:57:59
教えてください
Borland社のフリーのコンパイラを使用してるのですが
#defineをmakefileでのコンパイラ時に宣言するときはどのような記述がいるのでしょうか?

55:デフォルトの名無しさん
08/01/17 17:08:05
>>54
-D名前
-D名前=文字列

56:デフォルトの名無しさん
08/01/17 17:10:49
>>55
無事できました、ありがとうございます

57:デフォルトの名無しさん
08/01/17 17:56:37
>>54-56
ほのぼのした.

58:デフォルトの名無しさん
08/01/17 23:25:38
さてさて初心者が通りますよ。
今日から勉強しようと今、Visual C++ 2008 Express Editionをインストール中。

ここまでOKです。

59:デフォルトの名無しさん
08/01/17 23:27:07
>>58
帰ってよし

60:デフォルトの名無しさん
08/01/18 01:44:30
>>58
お前すごいな! VC2008をインスコしたのか
おれは、コンピラーすらインスコしてないよ
コンピラーぐらい、OSにおまけで付けて欲しいよな

61:デフォルトの名無しさん
08/01/18 03:00:22
最近の,NET Frameworkインストール済みなWindowsだと
C#とかVB.NETのコンピラーがおまけで付いていますよ、と。

62:デフォルトの名無しさん
08/01/18 10:03:24
金毘羅ー

63:デフォルトの名無しさん
08/01/18 10:21:21
emacsでc++するためのリンクを集めているのですが
URLリンク(d.hatena.ne.jp)
他にも何か有用なサイトをご存じの方
お教えいただけると幸せです


64:デフォルトの名無しさん
08/01/18 14:16:25
スレリンク(unix板)

65:デフォルトの名無しさん
08/01/19 18:29:00
C++好きですか?

66:デフォルトの名無しさん
08/01/19 19:33:18
Cのスーパーセットらしい  →普通
クラスを使えると便利 →やや好き
難解な文法というか落とし穴にハマる →嫌いになる(この辺で多言語に浮気)
テンプレートがわかってくる →再び好きになる
STLに感動する →好きになる
bind1stとかvalarrayに不満がでてくる →再びちょっと嫌いになる
boostがわかってくる →また好きになる


67:デフォルトの名無しさん
08/01/19 20:03:21
TMPができるようになる
 →何でもいいので何か自作のライブラリを作りたくなる

boostに追記/修正したくなる
 →何かを作る事よりもC++を書くこと自体が楽しくなる

既存のコンパイラに嫌気を射し
C++コンパイラを自分で作りたくなる
 →ちょっと飽きてくる

巨大なプログラムを作成中に過去に自分の書いたコードが読めなくなる
 →PCを窓から投げ捨てたくなる

68:引っ越してきました
08/01/19 20:17:46
VCスレからC++の問題ということで
追い出されて来ました。

クラスの中で+演算子を定義したいのですが、
newして、それをreturnの中で使いたいときに
deleteできないで困っています。
どうしたらよいでしょうか。

・簡単に言えば文字列の足し算です
・当方初心者です

friend Mojiretsu operator+=(const Mojiretsu& moji1, const Mojiretsu& moji2) {    // +演算子
  int tmp_nagasa = moji1.nagasa + moji2.nagasa ;
  char* tmp_moji = new char[tmp_nagasa+1];
  mojicpy(tmp_moji,moji1.s);
  mojicat(tmp_moji,moji2.s);
  return Mojiretsu(tmp_moji);
}

やりたいことはわかってもらえるとは思うのですが、
もっと楽にできるよとかもあったら教えてください。


69:デフォルトの名無しさん
08/01/19 20:23:50
いろいろとおかしいなw

70:デフォルトの名無しさん
08/01/19 20:24:06
Mojiretsu mojiretsu(tmp_moji);
delete[] tmp_moji;
return mojiretsu;

でどう?

71:デフォルトの名無しさん
08/01/19 20:44:36
>>68
newしないでMojiretuを定義してそれをreturnすれば?
Effective C++でもnewはするなと書いてあったぞ。

72:68
08/01/19 20:45:00
>>70
どうもです。
なるほど、コンストラクタを呼び出す、と。
実験の結果、ちゃんと動いています。
(まあ、もとのやつでも動いているようには
見えるのですが)


73:68
08/01/19 20:46:44
>>71
どうもです。
少々時間ください。初心者のため
理解するのに時間がかかりますので。

74:デフォルトの名無しさん
08/01/19 20:51:27
例外安全・・・についてはまだ触れない方がいいか
混乱しそうだし

75:デフォルトの名無しさん
08/01/19 20:52:05
>>68
なんぜ+=なのに、moji1がconstなんだ?

Mojiretsu s1("abc"), s2("def");
s1 += s2;

これでs1 == "abcdef"にならないとおかしいだろ。

76:68
08/01/19 20:55:56
訂正です。

ごめんなさい。
+=でなく、+です。

77:68
08/01/19 20:58:58
>>71
やっぱりわかりません。
もう少しヒントください。

あと、Effective C++のどの辺でしょうか。
そのうち読もうと買ってはあります。

78:68
08/01/19 21:00:50
>>74
とらいすろーきゃっち、でしょうか。
だいぶあとということでお願いします。


79:68
08/01/19 21:07:19
>>71

どこが分からないかというと、
Mojiretuを定義するには、
(コンストラクタに)文字列(char*)を
渡す必要がありますが、その文字列自体、
strcatした後のものにしなければならず、
どうどうめぐりのようで
よく分からないのです。
勘違い、ご指摘くださいませ。


80:デフォルトの名無しさん
08/01/19 21:08:26
>>77
誰がdeleteの責任持つの?って言う事。
それとEffective C++は
URLリンク(www.amazon.co.jp)
%E3%82%A2%E3%82%B9%E3%82%AD%E3%83%BC%E3%82%A2%E3%82%B8%E3%82%BD%E3%83%B3%E3%82%A6%E3
%82%A7%E3%82%B9%E3%83%AC%E3%82%A4%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%E2%80%95Ascii-Addison-programming/dp/4756118089

81:デフォルトの名無しさん
08/01/19 21:09:09
deleteは関数内で済ませてしまった方がいいだろう

82:デフォルトの名無しさん
08/01/19 21:12:07
Effective C++持っているなら演算子の話を是非、
と思ったらMoreのほうだった……、22。

operator +よりもoperator +=を実装しろ。

そして、operator +はこうする。
Mojiretsu operator +(const Mojiretsu& lhs, const Mojiretsu& rhs)
{
  Mojiretsu tmp(lhs);
  return tmp += rhs;
}

83:68
08/01/19 21:16:53
>>82
どうもです。
実はMoreも持っています。
また実験してみます。
(時間がかかります)

84:デフォルトの名無しさん
08/01/19 21:22:53
std::vector使え

85:68
08/01/19 22:00:52
>>82
ありがとうございました!
動きました!
+=を先に定義するというのは
頭いいですねえ。


86:デフォルトの名無しさん
08/01/19 22:12:44
頭がいいっつうか、定石だな。

87:68
08/01/19 22:20:59
>>86
そういうものなんですね。
>>82
「More」の22の最初のページの一番下に
「単独演算子がfriendである必要はまったくない」と
あり82でもfriendがついてませんが、friendにしないと、
lhsが"rerere"のような場合に私のではコンパイルエラーに
なったのですが、まだ何かおかしいということでしょうか。

88:デフォルトの名無しさん
08/01/19 22:24:53
>>87
publicなコピーコンストラクタはあるか。
+=もメンバならやはりpublicになっている?

82のは、private/protectedなメンバに全く触っていないから
friendにする必要がないという仕掛け。

89:68
08/01/19 22:32:41
>>88
たびたびありがとうございますです。
コピーコンストラクタも+=も+もその他すべての
メンバ関数はpublicになっているのですが。。。

90:68
08/01/19 22:37:36
あ、もしかして、+は82そのままではなく、
privateメンバを触っていますがそのせいでしょうか。

Mojiretsu operator+(const Mojiretsu& str1, const Mojiretsu& str2) { // +演算子
    String tmp_moji(str1.s);  //←コンストラクタにはクラスの文字列部を渡してます
    tmp_moji += str2;
    return tmp_moji;
}


91:68
08/01/19 22:57:13
friendがないと、
error C2804: binary 'operator +' に引数が多すぎます。
error C2333: 'Mojiretsu::operator +' : 関数宣言のエラーです。関数の本体は無視されます
っていうのも出たため、実験しましたが、
どの+でもエラーになってます。。。
friendつけている限りまったくwarningさえも出ないのですが。

すいません、時間切れです、明日の夕方、また来ます。

92:デフォルトの名無しさん
08/01/19 23:19:33
>>91
来なくていいよ
もっと勉強してから来い

93:デフォルトの名無しさん
08/01/19 23:26:25
>>91
迷惑です。もう荒らさないで下さい。

94:68
08/01/20 00:23:56
大変おじゃまいたしました。
自己解決いたしました。
(error C2804でググって英文を読みました。
確かに読んでいる本ではコード上ちゃんと
なっていますがはっきりと言葉では
書いてないんですよねー、、、)

>>88
や、その他の方々、重ね重ねありがとうございました。
大変勉強になりました。

95:デフォルトの名無しさん
08/01/20 00:48:41
>>94
とりあえず次回のためには自己解決の意味を覚えとけ。

96:デフォルトの名無しさん
08/01/20 02:31:03
でもクラス定義内でfriend関数を定義できるのは盲点だったと思っている。

97:デフォルトの名無しさん
08/01/20 09:50:57
>>96
最初から知っていた俺がいる。
ただ、ADLでしかlookupできないというのは盲点だったと思っている。

98:デフォルトの名無しさん
08/01/20 11:39:38
URLリンク(slashdot.jp)
終わってるスキルtop10にCが入ってる
c++と区別してcなのか、それともc++込みで終わってるのか

99:デフォルトの名無しさん
08/01/20 12:12:16
>>98
そいつバカですね。Cが終わってるなら、C++では重過ぎて
実装できない組み込み機器はどうなるのか?

100:デフォルトの名無しさん
08/01/20 12:31:48
アセンブラはリストされてないから大丈夫じゃないか?

101:デフォルトの名無しさん
08/01/20 12:59:28
古いネタの揚げ足とってどうすんだよwww

102:デフォルトの名無しさん
08/01/20 18:24:19
>>98
> c++と区別してcなのか、それともc++込みで終わってるのか
スラドのくだらない雑談はいいから元の記事嫁よ
って元の記事もかなりくだらないな

103:デフォルトの名無しさん
08/01/20 23:04:17
C++のコーディング方法について質問です。
皆さんは、コーディング中にコメントアウトを使うでしょうか?
以前、仲間内でコメントアウトの是非で議論になりました。
私の知人はコメントアウトを使用する派で、私は使用しない派です。
皆さんは、コメントアウトの是非についてどう思うかお聞かせください。
なお、開発はVC++6.0、2003、2005などで行っています。

ちなみに、私がコメントアウトを否定する理由は
1.ソースが汚くなるから。
2.バックアップなら、zipか何かにまとめてプロジェクトごとバックアップしておいた方が良いから。
の二点です。

よろしくお願いします。

104:デフォルトの名無しさん
08/01/20 23:38:02
コーディングスタイルはスレ違い。

コーディングスタイルにこだわるスレ
スレリンク(tech板)

105:デフォルトの名無しさん
08/01/21 06:53:46
(コメントがしきい値以下です。)

106:デフォルトの名無しさん
08/01/21 20:38:50
C++は難しすぎ 難易度:2
スレリンク(tech板)

107:デフォルトの名無しさん
08/01/22 17:37:57
英語圏向けblogでd.hatenaみたいにシンタックスハイライトできるblogないでしょうか?

108:デフォルトの名無しさん
08/01/22 17:45:39
スレタイ嫁

109:デフォルトの名無しさん
08/01/22 23:33:33
C++で作ればいーじゃない。

110:デフォルトの名無しさん
08/01/23 02:43:19
std::cerrやstd::wcerrの<<オペレータが例外を投げるケースは存在するのでしょうか?
これらをcatch文の中で使っても安全なのでしょうか?

111:デフォルトの名無しさん
08/01/23 08:49:57
>>110
標準ができる前に既にI/Oライブラリは存在していて、後方互換性
のためデフォルトではストリームは例外を投げない仕様だと思った。
exceptionメンバー関数を使ってストリームの各種状態を例外ハンドリング
に変えることは可能。

112:111
08/01/23 08:50:46
ユーザー定義型についてはoperator<<,>>で何をやるかによると思うけど。

113:110
08/01/23 14:51:51
>>111
basic_ios::exceptionsの存在に初めて気付きました。
おかげですっきりいたしました。
ありがとうございます。

114:デフォルトの名無しさん
08/01/23 16:24:22
C++ で new されたオブジェクト(o)とクラス(CLS)が与えられたときに、
そのオブジェクトが CLS クラスのオブジェクトか判定するには
どうすればできますか?

115:デフォルトの名無しさん
08/01/23 16:28:43
>>114
typeid演算子

116:デフォルトの名無しさん
08/01/23 16:34:33
クラスをCLSと表すあたり、COMのCLSIDじゃないかとエスパーしてみる。

117:デフォルトの名無しさん
08/01/23 17:11:05
>>115
thx

>>116
組込みですよ。

118:デフォルトの名無しさん
08/01/23 18:01:08
直接dynamic_castで済むこともあるけどな。

119:デフォルトの名無しさん
08/01/23 18:30:52
ただ、dynamic_cast と typeid は意味がちゃうよね。
dynamic_cast はキャスト可能な全ての型で判定が成功するけど、
typeid は(& とトップレベルの const 以外は)厳密に型が一致しないとダメ。
どっちの方がいいというのではなくて目的ごとに使い分けることになるから、
>>114 がどっちの判定がやりたいかによるね。

120:デフォルトの名無しさん
08/01/23 18:40:58
dynamic_castは多相型のポインタとリファレンスにしか適用できないし。

121:デフォルトの名無しさん
08/01/23 19:05:22
そうなるとそもそも仮想関数をうまく使えば
dynamic_castも要らないだろというところまで話を広げたくなるね。

122:デフォルトの名無しさん
08/01/23 19:28:59
今は typeid で分岐するのが流行りなんだぜ?

123:デフォルトの名無しさん
08/01/23 19:50:25
dynamic_cast じゃなくて typeid が必要になる状況ってあんま想像つかない。
どういう時に使うんだ?

124:デフォルトの名無しさん
08/01/23 21:03:45
デバッグ用途とかコードジェネレータとか

125:デフォルトの名無しさん
08/01/23 22:35:54
参照への参照
int& &

この表記はC++03では認められていませんが、C++0xではint&と等価なものとして
仕様が改定されることは決定済みなのでしょうか?

126:デフォルトの名無しさん
08/01/23 22:52:58
ドラフトには入ってたと思うよ

127:デフォルトの名無しさん
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
便利のようでそうでもないかな。変な副作用はなさそうだから気にしないでおこう。


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch