C++相談室 part62at TECH
C++相談室 part62 - 暇つぶし2ch1:デフォルトの名無しさん
08/05/27 23:53:59
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。

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

2:デフォルトの名無しさん
08/05/27 23:54:50
■基本■
[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/05/27 23:55:14
■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/05/27 23:55:56
■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/05/27 23:56:33
STLつかうと一気に実行ファイルサイズが10倍に?!

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

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

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

#include <stdafx.h>
後死ね。

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

6:デフォルトの名無しさん
08/05/27 23:58:15
前スレ C++相談室 part61
スレリンク(tech板)

7:デフォルトの名無しさん
08/05/27 23:58:27
1乙

8:仕様書無しさん
08/05/28 00:01:06
1乙

9:デフォルトの名無しさん
08/05/28 00:11:09
・(明示的・暗黙共に)コンストラクタ、デストラクタを定義していないこと
 → 親クラスが無いもしくは親もPOD型であること
 → メンバ変数が全てPOD型であること
 → 仮想関数を持っていないこと
でPOD型になるはず。

unionに突っ込んでコンパイル出来たらOK。

10:デフォルトの名無しさん
08/05/28 00:13:08
え、コンストラクタ持ってたら POD じゃないのん?マジ?

11:デフォルトの名無しさん
08/05/28 00:16:29
unionに突っ込んだ時に初期化で困るべ。

12:デフォルトの名無しさん
08/05/28 00:18:56
なるほど、超納得。

13:デフォルトの名無しさん
08/05/28 09:16:22
暗黙のコンストラクタってコンパイラが勝手に作るやつ?

14:デフォルトの名無しさん
08/05/28 09:26:30
>>9
暗黙定義のコンストラクタで POD じゃなくなるなら、 POD struct なんか作れないことになるぜ。

15:デフォルトの名無しさん
08/05/28 09:37:07
非explicitなコンストラクタのことじゃないの?

16:デフォルトの名無しさん
08/05/28 12:07:22
>>14
暗黙の空の実装のコンストラクタは、
「コンストラクタが無い状態」というふうに思ってくれ。
分かりやすくかつ適切な言葉が見つからなかったんで。

実際、union内のPOD型は、空のコンストラクタすら
呼ばれている事にはなってないしね。

17:デフォルトの名無しさん
08/05/28 12:16:53
>>16
それなら条件としては「明示的にコンストラクタ、デストラクタを宣言していない」でいいでしょ。
あーあと、コピー代入演算子も宣言しちゃだめな気がする。

18:デフォルトの名無しさん
08/05/28 12:20:25
>>17
「明示的」じゃ駄目なんだ。
空ってところが重要だから。

19:デフォルトの名無しさん
08/05/28 12:24:40
>>18
え? POD の条件にコンストラクタやデストラクタが空かどうかが関係あるの?
宣言した時点でアウトなはずなんだけど。

20:デフォルトの名無しさん
08/05/28 12:31:15
明示的なコンストラクタが無くても、
暗黙の空でないコンストラクタが作られたら駄目ってこと。

21:デフォルトの名無しさん
08/05/28 12:41:19
コンストラクタを必要とする(=非PODの)データメンバを持つ、以外に
暗黙のコンストラクタが生成される条件を思いつかないが。

あ、もちろん、仮想関数を持つなら必要だが。

22:デフォルトの名無しさん
08/05/28 12:43:01
あ、constメンバや参照メンバというのもあるな。
つっても、これは
コンストラクタ(コピーコンストラクタ)や代入演算子が
「暗黙には作られない」だけかもしれないが。

23:デフォルトの名無しさん
08/05/28 12:47:17
>>21
以外もなにも、それであってるよ。
>>9の矢印部分で書いた、
暗黙の空でないコンストラクタが作られる要因。

24:デフォルトの名無しさん
08/05/28 12:54:59
仮想継承も?
あんまり使わないけど

25:デフォルトの名無しさん
08/05/28 12:59:02
>9 がややこしいんだよ。矢印部分3つそろっててもコンストラクタ宣言してたら
POD じゃないし、そもそも「コンストラクタが無い」っていう認識も規格上はそうなって
ないわけで無理が出てくる。

クラス型が POD であるためには以下すべての条件を満たすこと。
・明示的にコンストラクタ、デストラクタ、コピー代入演算子を宣言していないこと
・基底クラスおよび非 static データメンバがあればすべて POD 型であること
・仮想関数を持たないこと
これでいいでしょ。

仮想継承は、インスタンスごとの情報としてポインタメンバいっこと同等に POD として
実装できそうな気がする。

26:デフォルトの名無しさん
08/05/28 13:01:45
>>24
たしか仮想継承も駄目だったはず。
昼休みオワタので去りまする。

27:25
08/05/28 13:04:07
んー前スレ最後に貼ってもらった規格の引用と比べると、 >25 でも微妙な違いがいろいろ
あるなぁ。継承した時点で POD じゃないっぽい。非 static データメンバについては
private/protected もダメ。

やっぱり正確なところは規格を見るのが一番ってことだねぇ。

28:デフォルトの名無しさん
08/05/28 13:26:01
理解させるために分かりやすく書いた説明と
厳密に伝えるための説明では目的が違うだろ

>>9-12の流れは前者
>>14-15は後者

規格には理由や経緯が書かれてないこともあるしな

要するにD&E最強

29:デフォルトの名無しさん
08/05/28 21:07:43
>>16
POD 型のデフォルトコンストラクタは0初期化するよ。
ただ、POD 型の変数を宣言しても
そのデフォルトコンストラクタも何も呼ばれない、というだけ。

30:デフォルトの名無しさん
08/05/28 22:38:46
デフォルトコンストラクタって0クリアしないんじゃないの?

31:デフォルトの名無しさん
08/05/28 22:48:06
#include <iostream>

struct X { int a, b; X() : a() {} };

int main()
{
X x;
std::cout << x.a << std::endl;
std::cout << x.b << std::endl;
return 0;
}

出力は

0
4262272

32:デフォルトの名無しさん
08/05/29 00:58:06
>>29 >>31
ビルトイン型のT()は0初期化の別記法なので、
デフォルトコンストラクタとは呼ばない

テンプレートのために、ユーザー定義型のデフォルトコンストラクタと
同じ記法が使えるようにしてあるだけ

[6.2.8]
The value of an explicit use of the constructor for a builtin
type is 0 converted to that type (§4.9.5).
Thus, int() is another way of writing 0.

For a userdefined type T, T() is defined by the default
constructor (§10.4.2), if any.

The use of the constructor notation for builtin
types is particularly important when writing templates.

Then, the programmer does not know whether a template parameter
will refer to a builtin type or a userdefined
type (§16.3.4, §17.4.1.2).

33:デフォルトの名無しさん
08/05/29 00:59:51
以下のコードなのですが、gcc3.4.4だと
could not convert template argument 'a' to 'void*'

と怒られます。
VC9.0では問題なくコンパイルが通ります。
どちらの動きが正しいのでしょうか?

template<void* T>

class A
{

};



void f(){}



int main(void)

{

A<f> a;


return 0;

}

34:デフォルトの名無しさん
08/05/29 01:05:16
まず、本やWebサイトでテンプレートの基本を勉強すべき

35:デフォルトの名無しさん
08/05/29 09:35:47
>>33
関数のアドレスを渡したいなら
template<void(*T)()>
では?

36:デフォルトの名無しさん
08/05/29 14:48:23
>>33
標準規格では、関数へのポインタから void* への変換は
認められてない筈。
VC は独自にこれを許してるけど。

37:デフォルトの名無しさん
08/05/29 15:38:09
struct X { int x; };
X func() { return X(); }
と定義したとき、

X().x = 0; は「左のオペランドが、左辺値になっていません」というエラーが出るのに
func().x = 0; がエラーにならないのはなぜですか?

38:デフォルトの名無しさん
08/05/29 15:58:25
規格でそうなのか、君の処理系特有のことなのか、俺は知らんけど、
とりあえず自分の処理系書いたほうが問題が整理されやすいんじゃないかな。

39:デフォルトの名無しさん
08/05/29 16:08:01
>>38 すみません。試したのは VC8 のみです。

40:デフォルトの名無しさん
08/05/29 16:30:09
>>33
関数のアドレスでなく、traitsを受け取るべき。

41:33
08/05/30 00:29:37
みなさんありがとう。

42:デフォルトの名無しさん
08/05/30 04:43:07
>>37
コンパイラは何?
規格ではどちらもOKのはず。

43:デフォルトの名無しさん
08/05/30 12:46:33
>>42
>>39 でも書きましたが VC8 です。
規格では非左辺値構造体の組み込み型メンバーでも書き込みOKということですか?

44:デフォルトの名無しさん
08/05/30 13:03:06
一時オブジェクトでも左辺値になれるだろ

45:デフォルトの名無しさん
08/05/30 13:23:39
>>44
え?一時オブジェクトは右辺値だろ?
一時オブジェクトが左辺値だったら他に何が右辺値になるんだ?

46:デフォルトの名無しさん
08/05/30 17:41:55
どちらも問題ないでしょ。一時オブジェクトは副作用が完了した時点で無効になるだけだから。
寧ろ、>37の「エラーが出るのに」という根拠を知りたい。

47:デフォルトの名無しさん
08/05/30 17:43:49
VC9でも>>37と同じエラーが出た。
どうもバグっぽいね

48:デフォルトの名無しさん
08/05/30 18:51:51
1 + 2 = 0 ができないのは対称性が悪い。

49:デフォルトの名無しさん
08/05/30 19:03:15
それは違う。

50:デフォルトの名無しさん
08/05/30 19:15:40
>>37
func().x = 0;がエラーにならないのって、
XがPOD型のときだけっぽい。

51:デフォルトの名無しさん
08/05/30 19:37:48
・コンストラクタを付けるだけ(PODでなくなる)で、
 func()経由でも出来なくなる。

struct X {
   int x;
   X(){}
};
...
X().x = 0; //エラー:左のオペ(ry
func().x = 0; //エラー:左のオペ(ry

・関数経由だと、どちらでも出来る。

struct X {
   int x;
   X(){}
   int& xref(){return x;}
};
...
X().xref() = 0;
func().xref() = 0;


誰か仕様詳しい人・・・

52:デフォルトの名無しさん
08/05/30 19:56:00
逆に POD の時にエラーにしてほしい。意味のない操作になるから。

53:デフォルトの名無しさん
08/05/31 02:12:49
>>33
うちではvc9は重すぎて入れてないので検証できないのだが、
なんでvc9だと通るんだ??

template <void * P>
class A {};
void *f() { return NULL; }
int main() { A<f()> a; return 0; }
だったらわかるけど。

54:デフォルトの名無しさん
08/05/31 02:13:29
>>36
自己レス。すまん、これか!
ほほぉ。ややこしいねぇ

55:デフォルトの名無しさん
08/06/01 19:52:42
>>32
>ビルトイン型で明示的に「コンストラクタ」を使って得られる値は
>0 をその型に変換した値になる、
と、「コンストラクタ」と書かれているわけだが。
んで引数なしだから明らかにデフォルトコンストラクタだろ。

56:デフォルトの名無しさん
08/06/02 21:07:16
初期化が終わっていないオブジェクトへの参照を関数へ渡すのは合法ですか。
その関数の中では、その参照からアドレスを得るか他の参照変数を初期化する操作しかしないとして。

57:デフォルトの名無しさん
08/06/03 00:09:19
前スレでもその話は出てて、アドレスや参照の保持だけなら問題無いだろう、
って言われてるけど、規格書レベルでの合法かどうかのソースは出てない。
規格書で保証があるなら、俺も知りたい所。

58:デフォルトの名無しさん
08/06/03 12:49:04
状態によって処理を変えたい時、Stateパターンで実装する方法と、enumとif文を使って実装する方法があると思います。
あとで状態の種類を増やしたくなった時、Stateパターンの方が保守しやすいと思っているのですが、
私が見てきたサンプルコードでは、enumを使っている例が多く感じます。
この2つの実装方法は、どのような事を考えて使い分ければいいのでしょうか?

59:デフォルトの名無しさん
08/06/03 17:54:50
stateパターンてどんなの?

60:デフォルトの名無しさん
08/06/03 22:19:05
状態ごとにオブジェクトを作りそれに動作をにまとめ、切り替える。


61:デフォルトの名無しさん
08/06/03 22:43:31
(1)とりあえずswitch
状態の数少ないし、stateにしてクラス数増えるのもしんどいし
あんまり変更もなさそうだからenumでswitchしちゃえ
増えるようならstateに書き直そう

(2)能力不足
state間で情報を共有する美しい方法が思いつかない
グローバル変数使うとアイツが怒るし・・・
そうだ、enumでswitchしとけば全部同一クラス内だから問題ナシ

62:58
08/06/04 12:33:24
>>61
どうもです。
小規模なものならenumで十分ということですか。
state間で情報共有ですが、各stateに親クラスへのポインタを持たせて~っていう方法では、
getter/setterが増えてしまうのが問題ということでしょうか。

63:デフォルトの名無しさん
08/06/04 18:20:21
class X { int x; friend class Y; };
class Y { int y; Y(X a) : y(a.x) {} };
のようにメンバ変数の初期化で private にアクセスできるでしょうか?

64:デフォルトの名無しさん
08/06/04 18:26:49
friend class Y; されてるんだから、YからXの中は丸見えだ。

65:デフォルトの名無しさん
08/06/04 20:42:00
Wから
xの
Yが丸見えだと?

ごめんなんでもない

66:デフォルトの名無しさん
08/06/04 21:26:45
また懐かしいネタを・・・w

67:デフォルトの名無しさん
08/06/05 10:33:50
URLリンク(kansai2channeler.hp.infoseek.co.jp)
buffonの針のシミュレーションでπを求めるプログラムなんですけど
Borland C++ Compilerでコンパイルすると
C:\borland\bcc55\src\C++>buffon.exe
Length of needle (0<L<=1): 1
Drop total of needle : 100
Number of hits = 55
Pi = 3.63636
という風にシミュレーション結果が出るんですが、
同じソースをcygwin g++(version4.2.4)でコンパイルすると
$ ./a.exe
Length of needle (<=1): 1
Drop total of needle : 100
Number of hits = 100
Pi = 2
という風におかしなシミュレーション結果になってしまうんですが、何が原因なんでしょうか?

68:デフォルトの名無しさん
08/06/05 11:26:10
>>67
y座標の乱数生成に問題がある。
rand()関数が返す値の最大値は定数RAND_MAXで判るけど、
これが65536前後しかないコンパイラは多数ある。
その式だとy座標には0か1しか返ってこない。

69:デフォルトの名無しさん
08/06/05 11:55:10
>>68
アドバイスありがとうございます。
ちゃんと動くようになりました。

70:デフォルトの名無しさん
08/06/05 19:41:00
クラスのtemplate化を考えています。
それで、templateで指定する型の取りうる範囲
を調べたいのですが、何か良い方法はありませんでしょうか?

template<T>
(略)

public:
int str[Tの取り得る範囲];

内部にこういう変数の宣言に関してもあるので・・・。

71:デフォルトの名無しさん
08/06/05 19:44:08
可算で上下限のある型なんて限られてるんだから特殊化すればいいだろ。

72:デフォルトの名無しさん
08/06/05 19:45:13
long longとか指定されたらどうするの?死ぬの?

73:デフォルトの名無しさん
08/06/05 20:05:30
std::numeric_limitsのmin(), max()

74:デフォルトの名無しさん
08/06/05 20:18:10
禿も禿本で言ってるな
numeric_limitsの特殊化も提供しろって

75:デフォルトの名無しさん
08/06/06 15:56:46
MinGWとVC++との連携を考えてて
下記みたいなソースを考えた。

GeoOpen関数へ引数無しだとちゃんとreturnされてくるんだが、
引数を作るとエラーが起こっちゃうんだよ。
printfはちゃんとされてるからまさにreturnでエラーが起こってる様子。
ちなみにエラー文はコレ↓
「The value of ESP was not properly saved across a funciton call.
This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.」

なんぞこれーー
コンパイラが違うから起こってるエラーなのか。。。

■MinGW側cpp(DLL作成側)
extern "C" __declspec(dllexport) int __stdcall GeoOpen(int inta) {
printf("%u", inta);
return 1;
}

■VC++側cpp(DLL読み込み側)
GEOOPEN geoOpen = (GEOOPEN)GetProcAddress(hGEOCODERDLL, "GeoOpen@4");
if (geoOpen != NULL){
int intRes = (*geoOpen)(testInt);
}

76:デフォルトの名無しさん
08/06/06 15:58:29
ちなみにVC++のヴァージョンは6.0

もしかしてスレチなのかな。

77:デフォルトの名無しさん
08/06/06 16:00:59
しまった記述し忘れ。
■VC++側cpp(DLL読み込み側)
testInt = 1;

78:デフォルトの名無しさん
08/06/06 16:05:27
GEOOPENの定義は?

79:デフォルトの名無しさん
08/06/06 16:07:09
C++にはDLLなんて概念ないしスレ違いだが
まあ呼び出し規約が一致してないんじゃないかなあ。

80:デフォルトの名無しさん
08/06/06 16:07:44
GEOOPENのtypedeで__stdcallを忘れているんじゃない

81:デフォルトの名無しさん
08/06/06 16:13:25
>>78
typedef int (* GEOOPEN)(int);
です。

>>79
やはりスレチでしたか。
失礼を。

82:デフォルトの名無しさん
08/06/06 16:16:12
>>80
ぐほー!

正にその通りでしたっ
ありがとうございます!

83:デフォルトの名無しさん
08/06/07 05:17:16
templateの型を強引にunsigned形式にキャストしたいんですが
どうやれば良いのでしょうか?
(unsigned T)num;
はエラーになってしまうので・・・。


84:デフォルトの名無しさん
08/06/07 05:32:20
Boostのmake_unsignedを使う。
あるいは自分で同等のメタ関数を書く。

85:デフォルトの名無しさん
08/06/07 05:43:10
質問です
ゲームを作るときに速度や位置といったよく変更するものは一箇所のヘッダーにまとめたほうがいいのでしょうか
それとも、その値を使うヘッダーごとに分けたほうがいいのでしょうか

前者だと、変更するたびにコンパイルの時間が長くなるし、
後者だと、書いてるヘッダーを探す手間が増えるというように、
長所と短所があるのでアドバイスをお願いします

86:デフォルトの名無しさん
08/06/07 06:19:35
>>73
固定配列のサイズ指定でmax() の戻り値使うと、可変長配列にならね?
C99なら問題無いけど、C++だと規格上不正のような気がする。

とはいえGCC4は通っちゃったので俺が間違ってるのか

>>70
boost使えるのならこういうのがあるYo
boost::integer_traits<T>::const_max

87:デフォルトの名無しさん
08/06/07 10:03:09
>>85
定義ファイルから読み込む

88:83
08/06/07 12:18:14
>>84
レスありがとうございます。
boostは環境で使えないので
メタ関数を書いたのですが・・・

template <typename T>
struct add_unsigned
{
typedef unsigned T type;
};

で、エラーが出ます。
unsignedではなくconstなどでは問題なくコンパイル通るのですが・・・


89:83
08/06/07 12:24:42
力ずくですが
template <class T> struct add_unsigned{ typedef T type; };
template <> struct add_unsigned<char>{ typedef unsigned char type; };
template <> struct add_unsigned<wchar_t>{ typedef unsigned int type; };
template <> struct add_unsigned<int>{ typedef unsigned int type; };

こんな感じで解決する事にしました。
どうもありがとうございました。

90:85
08/06/07 15:55:13
>>87
定義ファイルだとユーザが変更出来るという点が気になって使ってなかったんですが、
気にしなくていいのでしょうか
それとも配布前にコードに埋め込んで配布という形を取るのでしょうか

91:デフォルトの名無しさん
08/06/07 16:54:34
>>85
ヘッダで宣言してソースで定義すればいいんじゃないの?

92:デフォルトの名無しさん
08/06/07 17:50:01
>>90
コードに埋め込めばユーザーが変更できないとでも?


93:デフォルトの名無しさん
08/06/07 18:03:16
>>91
俺もそれ思ったけど、
定数自体よく増えそうじゃね?

その場合、定数取得用の関数に文字列渡して
ソースの方でマッピングするくらいしか無いと思う。

マクロ使って、開発中は関数+文字列渡しで、
リリース時は本当の定数にするのも手だけど、
うまいマクロ書けずに諦めた。

94:デフォルトの名無しさん
08/06/07 18:29:25
潤沢なCPU資源のある今の時代、別に毎回文字列をmapから探しても大して問題はないと思うな。
適当なテキストファイルにa=bの形式でひたすら列挙したものを読み込むクラスとか、そんなに手間でないし便利だから作っておくといいんじゃね?
俺は保存とかコメント付けもしたいからxml使ってるが。


95:デフォルトの名無しさん
08/06/07 18:42:44
おれは>>91の方法だな
>>93は同じような文字列(宣言と定義)を2箇所に書くのがいやだとかそういう話?

96:デフォルトの名無しさん
08/06/07 21:21:47
>>95
じゃなくて、値だけがよく変わるならそれ(cppの書き換えだけ)で良いけど、
定数が増える場合は宣言も当然追加しないといけないので、
ヘッダ書き換える事になって、
結局includeしてる全cppがコンパイルし直しになるな、と。

まぁ、>>85が定数増やすこと有るかどうか分からないけどね。

97:デフォルトの名無しさん
08/06/07 21:25:14
ヘッダ一つに定数一個だけ宣言して
定数使うソースは使う定数の分だけヘッダをインクルードすればいいんじゃね?

98:デフォルトの名無しさん
08/06/07 22:40:18
BCC 5.5.1であるテンプレートクラスの変数をメンバに持つクラスがいて、このクラスのヘッダの段階では
テンプレート引数にくるクラスが前方宣言されただけの時コンパイラに未定義の構造体と警告されてしまいます。
でもcppの方で実際の定義が分かるので、一応コンパイルは通ってるみたいなんですが、
コンパイラを黙らせるにはどのように書くのが良いのでしょうか?

ヘッダ
class hoge;
class piyo{
  sokuseki_ptr<hoge> hoggee;
};

ソース
struct hoge{ ~ }
(hoggeeの使用)

99:デフォルトの名無しさん
08/06/07 23:27:42
C++でDLL作成に挑戦しています

公開するAPI関数の定義(XXX.h)を extern "C" {} ブロックで囲っているのですが、
関数の本体(XXX.cpp)も同じように extern "C" {} ブロックで囲う必要があるのか分かりません
もちろんインターネットで検索をかけていますが、今のところ有用な情報がないです

両方とも囲う必要があるのか教えてください

100:デフォルトの名無しさん
08/06/07 23:36:28
>>99
試してみれば?


101:デフォルトの名無しさん
08/06/07 23:45:59
>>100
コンパイルは通りました
defファイルも作成できました

しかし、これで正しいのかが分からないのです

102:デフォルトの名無しさん
08/06/07 23:48:23
>>98
BCB2007の付属品のBCC5.9.3では何のエラーも警告も出ない。
5.5.1のバグというか癖では?

103:デフォルトの名無しさん
08/06/08 00:08:39

ソート済みのvectorに対してupper_boundで取得してきたイテレータから
そもvectorにおけるインデックス番号はどうやれば取得できるでしょうか?

104:デフォルトの名無しさん
08/06/08 00:11:18
std::distance()

105:デフォルトの名無しさん
08/06/08 00:24:29
>>99
名前マングルか名前マングリングでググれ。

106:デフォルトの名無しさん
08/06/08 01:22:37
>>104
ほんとだ。ありがとうございます!

107:デフォルトの名無しさん
08/06/08 01:33:02
>>105
いくつか有用な情報が得られました
ありがとうございました

108:デフォルトの名無しさん
08/06/08 02:07:53
質問です。
VC++2008を使用しているのですが
STLのvectorのsize()って、メソッドが呼ばれたらその都度数えているのでしょうか?
それとも、内部に、数量を管理する変数があって、その値を返しているのでしょうか?


109:デフォルトの名無しさん
08/06/08 02:11:13
実装次第。
VC6 の STL なんかは begin と end のポインタを保持していてその差を返してるが、
全ての STL でそういう実装になっているとは限らない。

110:デフォルトの名無しさん
08/06/08 02:11:44
普通はその都度数えます
とはいっても引き算1回
意味的には
vector<T> v;
v.end() - v.begin()
と同じ

111:デフォルトの名無しさん
08/06/08 02:17:45
数えるにしても、少なくとも O(1) の数え方ではある。
strlen みたいな O(N) の数え方はしていないな。

112:デフォルトの名無しさん
08/06/08 03:00:16
リストと違って定数時間が保証されてる

113:デフォルトの名無しさん
08/06/08 03:25:40
spliceとどっちを優先するかだね。

114:108
08/06/08 06:23:00
レスどうもありがとうございます。
それほど遅くはならない仕様なんですね。

今使ってるプログラムは
配列を使ってmalloc()で逐次拡張していくプログラムなんですが
これをvectorに置き換えたんですが、なんか100倍近く遅くなってるんですよね。
基本的に、配列と同じく[]しか使わなかったし
mallocで1つずつ拡張してた場所をresizeやらpush_backに置き換えただけなのに・・・。

元が1時間くらい回しっぱなしのプログラムなので、vectorに置き換えたら10時間くらいかかるようになってしまった・・・。

115:デフォルトの名無しさん
08/06/08 07:52:43
>>114
vectorは一般的に[]は速く、resizeやpushu_backは遅い。reservを調べよ。


116:デフォルトの名無しさん
08/06/08 08:28:37
FreeBSD7.0のgcc4.2.1では
vectorは1つの連続したメモリで管理しています。
resize()、push_back()は内部の配列のメモリは大体二倍ずつ増えるようになっています。
resize()は縮小しても内部のメモリを再割り当てしない様になっています。
STLのソースを読むのが早いのではないですか?


117:デフォルトの名無しさん
08/06/08 08:59:30
vector<A> v;
void f(vector<A> v);
f(v);
とかやってるんではないですか?
void g(vector<A>& v);
ではなく。

118:85
08/06/08 09:00:57
>>91-97
アドバイスを参考に色々考えた結果、ヘッダで宣言して定義をソースに書き、
設定する値は、デバック時はINIファイルやXMLファイルから読み込み、
配布時は埋め込んだコードを使うということにします。

アドバイスありがとうございました。

119:デフォルトの名無しさん
08/06/08 10:17:40
>>114
VC++2008のSTLはセキュリティのために色々やっていて遅い。
#define _SECURE_SCL=0を書いてからヘッダをインクルードすると
それがなくなってだいぶ速くなる。

120:デフォルトの名無しさん
08/06/08 10:41:43
>>119
そんなうえーんな事って他のコンパイラにもありうる?
例えば2005とか

121:デフォルトの名無しさん
08/06/08 11:42:21
むしろ2005からそうなった。

122:デフォルトの名無しさん
08/06/08 12:13:34
>>115
typo ひどすぎw

123:デフォルトの名無しさん
08/06/08 14:54:03
typoはコンパイラが教えてくれるから兵器だもん!

124:デフォルトの名無しさん
08/06/08 15:03:54
defalt:

125:デフォルトの名無しさん
08/06/08 17:34:26
カタカナでdefaultとか書こうとすると、typoで酷いことになるよね

126:デフォルトの名無しさん
08/06/08 17:43:43
defualt:とtypoしてラベルと見なされた事がある

127:デフォルトの名無しさん
08/06/08 17:47:00
>>120
セキュリティとはどんなセキュリティで
なにをしているんですか?

128:デフォルトの名無しさん
08/06/08 18:27:56
std::vector<int> hoge;
int* p = &hoge[0]; // NOT SECURE!!!

っていう

129:デフォルトの名無しさん
08/06/08 18:31:09
>>119
それわざわざヘッダに書かずコンパイラオプションでいいよな
ポータブルなC/C++コードをコンパイルしたいときは
その手の呪文をやたらと唱える必要あるよね、VC++8以降だと

130:デフォルトの名無しさん
08/06/08 18:33:15
>>127
operator []やイテレータでの範囲チェック。

ナントカ_sって関数に変えないCと違って、
何もしなくていいというのはC++さすがというべきところだけど、
どうしてもお節介という感じは否めない。

131:デフォルトの名無しさん
08/06/08 19:11:08
速度を落としてでも安全方向に振るっていうのは、C++の理念に反発してる。
そんなのはC#でやればいい話だ。

132:デフォルトの名無しさん
08/06/08 19:19:52
いつからお前の思想がC++の理念になったんだよ。

133:デフォルトの名無しさん
08/06/08 19:28:20
C++自体はオーバーヘッドは抱え込まない。
オーバーヘッドのある冗長なチェックをどこまで行うかは、ライブラリの実装しだいで使用者の自由ってことかな。



134:デフォルトの名無しさん
08/06/08 19:38:38
単なるデータ構造使いたい場合でも、
class使っちゃったら、コンストラクタが呼ばれてオーバーヘッドが起きたりとか・・・
工夫すりゃ回避できるけど、言語自体は"デフォルト"では、オーバーヘッドだらけでしょ。

135:デフォルトの名無しさん
08/06/08 19:43:07
>>134
コンストラクタが呼ばれてオーバーヘッド?
どんな場合の話だ?

136:デフォルトの名無しさん
08/06/08 19:43:20
プログラミング言語C++とC++の設計と進化をよむと
実効速度を重視して言語を設計してますよね。

137:デフォルトの名無しさん
08/06/08 19:46:30
>>134
>class使っちゃったら、コンストラクタが呼ばれてオーバーヘッドが
いいえ

>言語自体は"デフォルト"では、オーバーヘッドだらけでしょ。
いいえ

D&EのC++言語の設計ルールの章に書かれてるけど、
C++には「ゼロオーバーヘッドルール」というのがありまして。

138:デフォルトの名無しさん
08/06/08 20:24:49
オーバーヘッドをコントロールできるかどうかが問題だと思う

139:デフォルトの名無しさん
08/06/08 20:56:29
理想論でゼロオーバーヘッド言ってても
実際問題、速度差が出てるんだから、言い訳出来まい。

140:デフォルトの名無しさん
08/06/08 20:58:08
仕方ねーだろコードの肥大でCPUキャッシュからは溢れるし
仮想関数だって投機実行が効かないんだから

141:デフォルトの名無しさん
08/06/08 20:59:53
インライン展開するからコードの肥大化は関係なし


理想論だけどね ;-)

142:デフォルトの名無しさん
08/06/08 21:08:26
インライン展開するから肥大化すんだろ

143:デフォルトの名無しさん
08/06/08 21:13:07
Cでもコンストラクタや仮想関数と同じようなことをしようとすれば同じだけ時間がかかる。

144:デフォルトの名無しさん
08/06/08 21:14:33
C++はCのつもりで書けばCと同じ速度で動くんだよね。
ただ、速度を犠牲にして抽象化したくなる誘惑が多いということで。

145:デフォルトの名無しさん
08/06/08 21:21:11
わずかなパフォーマンスと引き換えに、抽象化をしてメンテナンスに有利なコードを書くのか。
それともメンテナンスを犠牲にしてベタコードでパフォーマンスを追及するかの選択は使用者が選べるのが利点だわな。

146:デフォルトの名無しさん
08/06/08 21:34:03
C++のfstream.writeはどうして第一引数がconst void*ではなくchar*なのですか?

147:デフォルトの名無しさん
08/06/08 21:40:17
理由は知らないけど、現実にvoid*してもキャストが減るわけでもないし、テンプレート書くときvoidの引数があるといろいろエラーが出るしメリットないもんな

148:デフォルトの名無しさん
08/06/08 21:58:28
basic_fstream<char>だからcharしか受け取らんという意図なんだろうけど、
バイナリ指向なwrite関数はvoid*が使いやすいよな。

149:デフォルトの名無しさん
08/06/08 21:59:08
というかなんでconstが無いのかと

150:デフォルトの名無しさん
08/06/08 22:04:59
charの配列しか動作は保証されないんじゃない?

151:デフォルトの名無しさん
08/06/08 22:09:55
え?constはあるだろ、流石に

152:デフォルトの名無しさん
08/06/08 22:12:39
>>149
実は俺も「マジで?」って思ってググッたw
大丈夫const付いてる。146が省略しただけ。

153:デフォルトの名無しさん
08/06/08 22:22:34
個人的にはmemcpyのsrcにconstが付いてて欲しい。

154:デフォルトの名無しさん
08/06/08 22:33:58
>>153
それもconstついているぞ。

155:デフォルトの名無しさん
08/06/08 22:35:51
じゃ、じゃあmainの第二引数にconstが付いて欲しい!

156:デフォルトの名無しさん
08/06/08 22:39:31
class A :public const B も許して欲しい。


157:デフォルトの名無しさん
08/06/08 22:42:33
むしろclass要らなくね?
structだけで良いよ。

158:デフォルトの名無しさん
08/06/08 22:59:10
>>157
classとstructの違いが分からないとは

159:デフォルトの名無しさん
08/06/08 23:05:22
template<struct T> asdf{ typedef T type };

typename asdf<int>::type;

160:デフォルトの名無しさん
08/06/08 23:26:55
>>158
分かった上で言ってるんだけど。
class無いと出来ないことってあったっけ?

161:デフォルトの名無しさん
08/06/08 23:32:05
template<typename T> asdf{ typedef T type };
いらねーな、やっぱw

162:デフォルトの名無しさん
08/06/08 23:33:01
>>148
basic_fstream<wchar_t> のことを考えると
已む無しなんだろうなあと思う。

163:デフォルトの名無しさん
08/06/09 00:22:27
>>160
こんなのとか

template <template <typename T> class U>

164:デフォルトの名無しさん
08/06/09 00:25:05
template <template <typename T> typename U>

もういっその事
template <(template <typename T>) typename U >
にしちゃえば良かったのに

165:デフォルトの名無しさん
08/06/09 00:33:24
template <typename T> class U { };
をそのまま突っ込む形(現状)がベストだと思うけど。

166:デフォルトの名無しさん
08/06/09 00:38:57
template <template <typename T> class U>
がよくて
template <template <typename T> typename U>
template <template <typename T> struct U>
がダメな理由がわからん。


167:デフォルトの名無しさん
08/06/09 00:39:49
たしかに本質的にはclassは無くてもいいが、構文上は必要だな
ただ、元からclassが無ければ↓という構文になっていただろうけどな
template <template <typename T> struct U>

まぁ、あの偉大な禿も万能なわけじゃないからな

168:デフォルトの名無しさん
08/06/09 00:41:49
class でも struct でも OK にして、
それなら typename も OK でいいだろって感じにして・・・
って感じに C++0x でなったりするのかな。

169:デフォルトの名無しさん
08/06/09 00:55:47
classの方が打ちやすいYo

むしろstructを非推奨に


ところで何で、びよよん先生を禿っていうの?
ハゲてるから?ハゲだから?


170:デフォルトの名無しさん
08/06/09 01:06:07
英語ネイティブな人間にはclassという単語がしっくり来るからでしょ
C++の誕生当時はオブジェクト指向は一般的じゃなかったから
言語側がユーザーを啓蒙する必要があったんだと思う

171:デフォルトの名無しさん
08/06/09 01:36:18
classっていうと階級が最初に出てくるんじゃないかな
階級闘争でいうところの階級な
中産階級とか、総中流意識とか
ブルーカラー、ホワイトカラーとか
そういうイメージ


嘘だけど

172:デフォルトの名無しさん
08/06/09 08:52:46
classって1年2組のことでしょ

173:デフォルトの名無しさん
08/06/09 19:20:37
classはsimulaから来たのでしたよね?

174:デフォルトの名無しさん
08/06/09 19:58:32
1993に恋をして君に夢中なんでしたよね

175:デフォルトの名無しさん
08/06/09 21:06:43
後ろ後ろ!

176:デフォルトの名無しさん
08/06/10 14:37:26
パーマン乙

177:デフォルトの名無しさん
08/06/10 18:25:19
std::basic_fstream<unsigned char> は使っても問題ないでしょうか?

178:デフォルトの名無しさん
08/06/10 22:36:39
>>177
見慣れないうえにあんまり意味無いと思うからお勧めはしない。

179:デフォルトの名無しさん
08/06/10 23:31:49
char_traits が定義されてないとダメなんじゃないかな。

180:デフォルトの名無しさん
08/06/11 01:13:48
std::basic_fstreamがstd::iostreamみたいにC++に規格として盛り込まれているのか、
あるいは処理系に依存するのかをききたいんじゃね

181:デフォルトの名無しさん
08/06/11 01:15:29
>>179 なるほど
それでは std::char_traits 相当の UcharTraits を定義して
std::basic_fstream<unsigned char, UcharTraits>
とすると使えるでしょうか?

182:デフォルトの名無しさん
08/06/11 01:16:29
理論上は使えるんじゃないかな? 多分。

183:デフォルトの名無しさん
08/06/11 01:41:47
>>180
やりたいことは
put( unsigned char ) と write( const unsigned char*, streamsize )
を使ってバイナリデータをファイルに書き込むことです。
このとき1バイトは0から255を表現できないといけないので最低 unsigned char の型が必要です。
型が char の場合、どの処理系でも使える範囲は0から127までなので目的を果たせません。

184:デフォルトの名無しさん
08/06/11 01:54:15
>>183
バイナリデータとしてみると算術型は違ってもビットパターンを変更しないキャストは実質的に同じデータを指す。
writeはchar*を引数に取るけど、そのポインタがintであれwchar_tであれエンディアンとサイズが正常であれば問題ない。
つまり任意のデータのポインタをchar*として見ることは、その先にあるデータをビットパターンを変更せずにキャストする事に相当する。

185:デフォルトの名無しさん
08/06/11 02:01:01
>>184
キャストとはちょっと違う。 char* はオブジェクトの内部表現となる
メモリの読み出し~書き込みに使えることになっている。これは
unsigned char も signed char も同じ。

ってことで、バイナリ出入力したいだけなら普通の fstream で十分。

186:デフォルトの名無しさん
08/06/11 02:15:47
ios::binary を指定しておけば
fstream で何の問題も無くバイナリの入出力ができる。

187:デフォルトの名無しさん
08/06/11 13:00:02
>>185
それは仕様書で言えばどのあたりで分かるでしょうか?
JIS X 3010-1993 は6章ぐらいまで目を通したのですが見当たりませんでした。

188:デフォルトの名無しさん
08/06/11 16:23:35
エンディアンについても実装がバラバラなのが許容されるのにオブジェクトの内部表現って言及されてるの?

189:デフォルトの名無しさん
08/06/11 16:39:28
>>187
185じゃないけど、
ISO/IEC 9899 [6.5.3.4] でどう?
sizeof(char)==1の保証 → 単位粒度で扱えることの保証。

190:デフォルトの名無しさん
08/06/11 16:56:05
これかな

3.9 Types
2 For any object (other than a base-class subobject) of trivial type T, whether or not the object holds a valid value of type
T, the underlying bytes (1.7) making up the object can be copied into an array of char or unsigned char.36) If the
content of the array of char or unsigned char is copied back into the object, the object shall subsequently hold its
original value.

36)By using, for example, the library functions (17.4.1.2) std::memcpy or std::memmove.

191:デフォルトの名無しさん
08/06/11 17:14:51
>>724
ID出る板限定+多少巻き添え有りで良ければ、
NGワードのIDの欄に「O」を加えると消せる。

192:デフォルトの名無しさん
08/06/11 17:17:35
もちろん誤爆

193:デフォルトの名無しさん
08/06/11 17:24:40
そんなあなたに性器表現

194:デフォルトの名無しさん
08/06/11 18:24:26
VBでビルドすると100KBくらいだったプログラムを
ほとんど同じ構成(コード)でC++に移植したらサイズが900KBまでふくらみました
これって正常ですか?

VS2008、C++ 非MFCのアプリケーションです

195:デフォルトの名無しさん
08/06/11 18:28:09
ヒント: VBランタイムのサイズ

196:デフォルトの名無しさん
08/06/11 18:32:28
デバッグビルドしてるっていうオチでは?

197:デフォルトの名無しさん
08/06/11 18:39:43
>>195
C++はランタイムライブラリが大きいということですか?


>>196
いえ、リリース用のビルドでそのサイズです
最適化オプションも分かる範囲で変更してみましたが あまり変化なしでした

198:デフォルトの名無しさん
08/06/11 18:43:50
>>197
VBはランタイムDLLが別だからその分を考慮しろ。

199:デフォルトの名無しさん
08/06/11 18:44:49
VBランタイムのサイズをご存知ないのか
URLリンク(www.microsoft.com)
>ダウンロード サイズ : 1.0 MB
>Visual Basic 6.0 を使用して作成されたあらゆるアプリケーションは、これらのファイルを必要とします。

200:デフォルトの名無しさん
08/06/11 18:48:10
>>198-199
>>194のはVS2008のVBですが
それもDLLが別ということですよね?

201:デフォルトの名無しさん
08/06/11 18:48:24
現実にはそれで足りないプログラムが多数。

202:デフォルトの名無しさん
08/06/11 18:50:36
>>200
VB 2008のランタイムたる.NET Frameworkは数百MBある。

あと、一応聞いておくが、C++製はCLRフォームアプリケーションじゃないほうだよね?

203:デフォルトの名無しさん
08/06/11 18:52:49
>>202
>C++製はCLRフォームアプリケーションじゃないほうだよね?
それです

204:デフォルトの名無しさん
08/06/11 20:28:33
>>190
なかなかいい情報ありがとう。
でもここでいっているコピーって memcpy() や memmove() を想定しているような気がする。
普通に char, unsingned char ポインタ経由で代入した場合も同じことが言えるのかな?

205:デフォルトの名無しさん
08/06/11 21:48:42
クリティカルセクションについて質問です。

クリティカルセクション用のクラスを作成しています。
外部からCRITICAL_SECTION構造体を渡さなくても済むように、
staticなメンバ変数としてCRITICAL_SECTIONオブジェクトを作成し、
それに対してInitializeやEnter、Leave、Deleteを行うようにしています。

しかし、ネット上で似たようなコード見つけられていないことから、
本当にこれでスレッドセーフが実現できているのか不安です。

何か問題はありそうでしょうか?

206:デフォルトの名無しさん
08/06/11 22:46:43
>>205
それだとお互いに無関係なクリティカルセクション同士でも排他してしまうな。
というか、二重にInitializeとかDeleteとかしてしまうのでアウト。
CRITICAL_SECTION構造体は非staticなメンバ変数にすればよろし。

207:デフォルトの名無しさん
08/06/11 23:11:40
>>206
なるほど、考えが足らなかったです。
ありがとうございます。

208:デフォルトの名無しさん
08/06/12 00:14:55
こういう時って、コンストラクタでInitialize、デストラクタでDeleteするのが
いいんだっけ?

209:デフォルトの名無しさん
08/06/12 00:27:16
もう1つ、コンストラクタでEnterしてデストラクタでLeaveするクラスも欲しい。
いかにもWinSTLが持っていそうだ。

210:デフォルトの名無しさん
08/06/12 00:37:07
boostも持ってるな

211:デフォルトの名無しさん
08/06/12 02:49:00
>>204
190 は明らかに char や unsigned char の配列として(ポインタ経由で)読み書きした
場合のことを想定した記述だろ。


ほかには 3.10 p15 にある aliasing rule でも char, unsigned char だけ、
そういう直接アクセスを許すように特別扱いされてたりすることから、任意のオブジェクトに
対する char, unsigned char 経由でのアクセスは規格の意図として想定されているものと
考えられる。

よく見ると signed char はダメみたい。微妙だなー。

212:デフォルトの名無しさん
08/06/12 12:08:09
charがsignedならどうなるの?

213:デフォルトの名無しさん
08/06/12 12:14:00
char と signed char と unsigned char はそれぞれ別の型
char が符号付きでも符号無しでも signed char とは関係ない

214:デフォルトの名無しさん
08/06/12 12:33:31
VBでは下記のように宣言して 違うクラスからでも sub.関数() が使用出来ていたのですが
c++で同じ構成の共通関数を作ろうとしても参照エラーが出てうまくいきません
下記のコードをc++用にした場合 クラス、関数はそれぞれ
どのように宣言するのが正しいでしょうか?

Public Class main

    Sub ボタンクリック イベント
         sub.関数()  '違うクラスの共通メソッド呼び出し
    End Sub

End Class

Public Class sub

  Public Shared Sub 関数()
  End Sub

End Class

215:デフォルトの名無しさん
08/06/12 12:43:19
>>214
C++のソース貼らないと答えようがない。

216:デフォルトの名無しさん
08/06/12 12:44:18
class main {
public:
 void button_click_event();
};

class sub {
public:
 static void kansu();
};

void main::button_click_event()
{
 sub::kansu();
}

void sub::kansu()
{
}

たぶんこんな感じ?

217:デフォルトの名無しさん
08/06/12 13:10:00
>>215
namespace test {//Namespace

public ref class Form1 : public System::Windows::Forms::Form{//Class Form

private: System::Void code_Click(System::Object^  sender, System::EventArgs^  e) {//イベント
sub::kansu(); //共通関数 呼び出し
}//イベント

};//Class Form


class Sub{//Class Sub
public :
void kansu();
};//Class Sub

void Sub::kansu(){// 共通関数
};//共通関数

}//Namespace

こんな感じです、共通関数を違うClassのForm1から呼びだして使いたいのですが
識別子が見つからない等のエラーが出てうまくいきません

>>216
そのコードのように修正してみましたが
クラス、識別子が見つからないという同じエラーが出てだめでした

218:デフォルトの名無しさん
08/06/12 13:22:02
・void kansu() に static を付ける
・sub::kansu() の呼び出しは sub の定義よりも下で行う
・class Sub と sub::kansu で sub の大文字と小文字が異なる

219:デフォルトの名無しさん
08/06/12 13:25:47
あと
・エラーメッセージは一字一句正確に書け

220:デフォルトの名無しさん
08/06/12 13:29:36
>>218
うまく動きました、みなさんどうもありがとうございます

>・class Sub と sub::kansu で sub の大文字と小文字が異なる
コードではちゃんとなっているのですが
ここに書くときに記述ミスしていました、申し訳ないです

221:デフォルトの名無しさん
08/06/12 18:17:23
>>211
3.9 p2 は
「そのオブジェクトを構成するバイトは、char または unsigned char の配列にコピーできる」に対して
「例えば、ライブラリ関数 std::memcpy または std::memmove を使って」という注釈があるけど
char 配列の要素ごとの代入でコピーできるなら「std::memcpy や std::memmove も含まれる」のような
ニュアンスで注釈を付けるんじゃないかな?

それと 3.9 p2 はあるオブジェクトを char 配列にコピーして、その配列から元のオブジェクトにコピー
したときにオブジェクトが元の内容に戻ることを保障しているだけで、同型の他のオブジェクトに対しては
どうなるか分からないんじゃない?
3.9 p3 では char 配列を通さずに std::memcpy でコピーすればオブジェクトが同じ内容になるようです。

3.10 p15 は未定義ではないだけで結果は処理系定義ということもありえるんじゃない?


222:デフォルトの名無しさん
08/06/13 07:57:56
>>221
> char 配列の要素ごとの代入でコピーできるなら「std::memcpy や std::memmove も含まれる」のような
> ニュアンスで注釈を付けるんじゃないかな?
"for example" って書いてあるんだから、そういうことだと思うよ。


1.7, 1.8 より、 POD 型のオブジェクトはメモリ上で連続する
バイト列とされている。

3.9.1 p1 により、 char, unsigned char はバイト中のすべての
ビットが値に反映されることになっているので、これらの型を介して
バイトを正確にコピーできる。

memcpy などの動作は引数の指すメモリ上の位置から連続する
バイト列に対する操作として定義されているので、 char* を使って
同様にバイト列をコピーするコードを書けば同じ意味になる。

そのような操作に対する意味が 3.9 p2, 3.9 p3 の範囲で確定する。
これ以外のバイト操作( POD 型のオブジェクトに属さないバイトの
操作や、オブジェクトひとつに満たない部分的な操作)については
意味も動作も規定はない。(不定?)

223:デフォルトの名無しさん
08/06/13 08:14:03
違うフォーム上のテキストボックス等のデータを取得するにはどうすればいいですか?

224:デフォルトの名無しさん
08/06/13 08:21:14
C++にフォームなんて概念ありません

225:デフォルトの名無しさん
08/06/13 10:20:30
>>223
初心者スレ、もしくはMFC, WTL, C++/CLIなどで該当するスレへ。
開発環境は必ず書くこと。

226:デフォルトの名無しさん
08/06/13 11:52:30
array<String>型の2次元配列 data[40][40] を作りたいのですが
array<String^> ^data = gcnew array<String^> (40)(40);
とするとエラーが出ます

どうやって宣言したらいいですか?

227:「CLI」で探せ
08/06/13 12:04:18
>>226
そんな気持ちの悪い記法は専用スレへどうぞ。

228:デフォルトの名無しさん
08/06/13 12:23:01
>>226
CLIはC++じゃないのですれ違い。

229:デフォルトの名無しさん
08/06/13 13:51:26
>>228
じゃ CLIなC++は何言語なんだよ?w
バカかお前ww

230:デフォルトの名無しさん
08/06/13 13:55:45
C++/CLI

231:デフォルトの名無しさん
08/06/13 14:00:53
A.hで中身まで記述した
static void Func()
{
 ・・・
};

を B.cpp、C.cppそれぞれでインクルードすると実体はそれぞれにできるんでしょうか?

232:デフォルトの名無しさん
08/06/13 14:02:42
>>229
>227

233:デフォルトの名無しさん
08/06/13 14:03:33
>>229
C++/CLIはC++を拡張した別の言語としてEcmaで標準化されてるよ。

234:デフォルトの名無しさん
08/06/13 14:03:59
>>231
はい。但し、そのFunc()を例えばB.cppでは使いC.cppでは使わなかったとすると、一つだけになるかもしれません。
# 勿論、どちらでも使わない場合は一つもないかもしれないわけで。

235:デフォルトの名無しさん
08/06/13 14:05:25
まぁそれをやるならせめて無名名前空間をつかってほしいところ

236:デフォルトの名無しさん
08/06/13 14:13:59
>>234
うわぁぁ。そうなんだ。
staticつければ必ずひとつになると思っていました。ありがとう。
こういう場合ひとつだけにするにはテンプレートにするしかないのかな。
ヘッダに記述すること自体の是非は別として。


237:デフォルトの名無しさん
08/06/13 14:19:46
>>236
いや、テンプレートにするかしないかとstaticかどうかは別の問題だから。
つーか、>231の場合でもどうせインライン展開されるから消えてなくなると思うし、
テンプレート関数にしたところでインライン展開されなければ複数できてもおかしくはない。

で、一つにしたい積極的な理由があるの?

238:デフォルトの名無しさん
08/06/13 14:42:06
いろいろ言われそうだけどVCのプリコンパイル済みヘッダーの#include <stdafx.h>
が嫌だからなんです・・。
いろいろなコンパイラで使えればな~と思っていたらどうしてもこれが邪魔で。
プリコンパイル済みヘッダーの設定変えればいいのでしょうけど、ファイルをコピー、
includeですぐに使えるような書き方はないかな~と。


239:デフォルトの名無しさん
08/06/13 14:50:41
あ、見当違いなこと書いてたかも。
上記理由でどうせ同じ関数なんだからひとつにしてファイルサイズ減らせないかなと
思っていた次第です。

240:デフォルトの名無しさん
08/06/13 14:52:05
>>239
理由がそれだけなら、最適化するとどうせインライン展開されて消えてなくなるから気にするな。

241:デフォルトの名無しさん
08/06/13 15:27:25
というか、あちこちに同じ中身が生成されるわけだから
ファイルサイズは逆に増えるよね。

242:デフォルトの名無しさん
08/06/13 15:33:47
う~ん、いろいろありがとう。
とりあえず最適化に任せてみます。

243:デフォルトの名無しさん
08/06/13 16:11:17
===foo.h===
#include "bar.h"
class foo
{
(略)// barは出てこない
};

===foo.cxx===
#include "foo.h"
(略)// barが出てくる

とやるのと、
#include "bar.h"
をfoo.cxxの中に持ってくるのは、
どちらにどういうメリットデメリットがあるのでしょうか。
また、一般的にはどちらの書き方が推奨されますか。

244:デフォルトの名無しさん
08/06/13 16:13:13
CLIって便利だよな
特に他言語で作ったクラスライブラリがそのまま使えるお得感は感動ものだ

245:デフォルトの名無しさん
08/06/13 16:17:15
>>243
ヒント:依存関係、カプセル化

246:デフォルトの名無しさん
08/06/13 17:46:14
>>243
後者。素直に使う所に書く、で必要十分。
前者にメリットは無い。fooを使うやつのコンパイルがbar.hの分遅くなるだけ。

247:デフォルトの名無しさん
08/06/13 18:14:43
次のプログラムをエラー無くコンパイルしたいのですが、方法を教えてください。
//データの構造体-----------
struct dataA
{
int m_dataA;
CLSA * m_next //クラスのポインター
};
//使用するクラス------------
class CLSA
{
dataA m_dat[100];   //データの配列
};
dataAの中にクラスのポインターを持つ。この状態ではCLSAが無いと言われます。
順番を変えるとクラスの中でdataA構造体が無いと言われます。
対処方法が無いでしょうか?


248:デフォルトの名無しさん
08/06/13 18:16:41
セミコロン抜けてた
CLSA * m_next; //クラスのポインター

249:デフォルトの名無しさん
08/06/13 18:32:36
>>247
struct dataAの上に 「class CLSA;」を書く。

あと、どうでもいいけど何かよく分からないデータ構造だな。
dataA{ CLSA* m_parent; } とか
dataA{ dataA* m_next; } とか
CLSA{ CLSA* m_next; } なら分かるけど。

250:デフォルトの名無しさん
08/06/13 20:00:26
出来ましたありがとうございます。基本的な内容ですねorz
データ構造は
root クラスインスタンス
|
|-ノード1クラスインスタンス
| : |-ノード1クラスインスタンス
| : |-ノード1クラスインスタンス
| :
|-ノード1クラスインスタンス

のような多段構造のようなもので、ノード分岐の意味をdataAの内部で示しています。
意味自体が単独で作られたり渡されたりするので、1つの構造体にしています。

251:デフォルトの名無しさん
08/06/13 20:08:54
>>244
そのままシームレスに使えればだがな。

だが現実は・・・・ ハァー

252:デフォルトの名無しさん
08/06/13 22:04:32
>>222
3.9.1 p1 は「バイト中のすべてのビットが値に反映される」とはいっても、ビット列と値が
1 対 1 でないこともあるんじゃないかな。
例えば char が符号付きで符号ビットと絶対値で表現する場合、値 0 を表現するビット列が
2 パターンある。その処理系で char* を通して値 0 を読み、その値を char* を通して書く
とビット列が変わる可能性があるんじゃないかな?

253:デフォルトの名無しさん
08/06/14 00:03:39
char型のコピーはbit列をそのままコピーすると言っているのでは

254:デフォルトの名無しさん
08/06/14 04:05:09
>>252
現行の規格で多少無理やり解釈すれば、 -0 と +0 は == で比較すれば
同じになるとしても、区別可能な(異なる value representation を持つ)二つの値
ということでコピーでビット列が変わる可能性は無い、とは言えそう。

ちょっと苦しいんで調べてみたところ、 C との互換性と合わせて見直しが
提案されているみたい。
URLリンク(www.open-std.org)
この中で C99 の規格を基本的にはそのままパクりながら、 C99 では
保証が無いものの、 C++ で半ば慣習的に行われてきた char による
object representation のコピーを保証するため、以下のような記述の追加が
見られる。

The types unsigned char and char may be used for “bitwise” copy.
[Note: this means that if signed char has a negative zero which is
either a trapping value, or will be forced to positive zero on assignment,
plain char must be unsigned. ?end note]

てきとう訳:
型 unsigned char と char は「ビット的」コピーに使ってもよい。
[注: これは、もし signed char が負のゼロをトラップ値として持つか
代入において正のゼロに強制されるのであれば、ただの char は
unsigned でなければならない、ということを意味する。 -注ここまで]

提案とは別に、議論の中では C++ では2の補数を強制してしまうような話も
出ていたらしい。実際のところはそれでもいいのかもしれない。

255:デフォルトの名無しさん
08/06/14 13:48:22
以下のような二種類の構造体のフィールドなのですが、
どちらがより適切なのでしょうか?

struct A
{
int length; // textの長さ
unsigned char text[0]; // 利用者側で好きに領域を確保して先頭を格納。
};

struct B
{
int length;
unsigned char text[1];
};

違いはtext[1]とtext[0]だけなのですが、
text[1]としてしまうと、

unsigned char text[] = "aiueo";
A* a = (A*)malloc(sizeof(A) + strlen(text));

としたときに(処理系依存ですが)
intで4バイト、unsigned charがパディングされて4バイト
さらに文字列の長さで5バイト確保されます。
これだとunsigned charがパディングされた4バイトは無駄な領域の気がします。

text[1]とするメリットはあるのでしょうか?


256:デフォルトの名無しさん
08/06/14 14:12:25
>>255
宣言より大きい配列のアクセスはお勧めできないと思う。
環境依存なしでそういう構造を作りたいなら
struct A
{
int length; // textの長さ
};
A* a = (A*)malloc(sizeof(A) + strlen(text));
で確保して
char* buff=(char*)(a+1);
で文字列にアクセス


文字列の構造体を作りたいなら以下の方がお勧めかな
struct A
{
int length; // textの長さ
unsigned char* text;
};

257:デフォルトの名無しさん
08/06/14 14:24:31
>>255
unsigned char text[0]; はC89では認められていない。
C99から導入されたflexible array memberを使うなら、
unsigned char text[];

258:デフォルトの名無しさん
08/06/14 14:58:10
>>254
なるほど。
今回初めてC++の仕様書に目を通してみたけど未定義や処理系定義の部分が多くて
正確に解釈するのははなかなか難しいですね。
現状の処理系に合わせて処理系定義の部分を削っていけばかなりシンプルになると
思いますけど。

259:デフォルトの名無しさん
08/06/14 15:18:36
>>258
処理系を前提とした入門書を読もう。 処理系未定義はその後で。

260:255
08/06/14 19:20:57
>>256さんどうもありがとうございます。

struct A{
int a;
unsigned char c[0];
};

gcc -c -pedantic test.c
としたら警告が出ました。

警告: ISO C forbids zero-size array 'b'

gccの独自拡張で可能になっているけれどC89自体では禁止されている
ということですね。

261:デフォルトの名無しさん
08/06/14 20:30:10
おい、お前ら、googleでソースコードの検索ができることを知ってましたか?
URLリンク(www.google.co.jp)

262:デフォルトの名無しさん
08/06/14 20:31:46
お前が今まで知らなかったことに驚愕。

263:デフォルトの名無しさん
08/06/14 20:32:49
どういうときにつかうん

264:デフォルトの名無しさん
08/06/14 20:34:41
codeをsearchする時

265:デフォルトの名無しさん
08/06/14 20:54:24
>>261-264自演乙

266:デフォルトの名無しさん
08/06/14 20:56:31
>>265
自演じゃねーよ、タコが

267:デフォルトの名無しさん
08/06/14 20:58:47
>>266
イカですけど何か?

268:デフォルトの名無しさん
08/06/14 20:59:26
>>267
創価、すまんかった

269:デフォルトの名無しさん
08/06/14 23:11:26
# include<iostream>

using namespace std;
void func(int a = 0,long int b = 1000, double c = 2.9751)
{
cout<<"This is func[i].\n";
cout<<"a="<<a<<", b="<<b<<", c="<<c<<"\n\n";
}

void func(int a,double b =3.4152)
{
cout<<"This is func[ii].\n";
cout<<"a="<<a<<", b="<<b<<"\n\n";
}

void func(long int a)
{
cout<<"This is func[iii].\n";
cout<<"a="<<a<<"\n\n";
}


int main(void)
{
func(0,1000,2.9751);
func(0,3.14152);
func(0);
return 0;
}
オーバーロード関数が呼び出せませんと言うエラーが出るのですが、
何処が間違えているかわかりませんか?
未熟な私に教えていただけたらありがたいです。

270:デフォルトの名無しさん
08/06/14 23:16:36
そんな
かわいそうな
つかいかたを
するな

271:デフォルトの名無しさん
08/06/14 23:22:17
>>269
どれを呼んでいいのかワカンネ。とコンパイラ様は仰っておられる


272:デフォルトの名無しさん
08/06/14 23:23:24
>>269
とりあえず、2個目と3個目のfuncを関数ごと
コメントアウトして実行してみ。

273:デフォルトの名無しさん
08/06/15 02:27:52
もう引数全部意図する型にキャストしちゃえよ

274:デフォルトの名無しさん
08/06/15 02:40:25
既定引数と多重定義は「まぜるな危険」だろ。
危険といっても、だいたいコンパイルエラーか警告だけど。

必要なら既定引数を使わないで多重定義をがんばることもやる。
といってもこういうのはありにしているが。
void f(int x);
void f(double x);
void f(int x, int y, int z = 0);
//実引数1個なら多重定義の解決の候補に既定引数は関係しない。
//実引数2個ならデフォルト引数を使うがfの候補は1つに決まっているので良し。

275:デフォルトの名無しさん
08/06/15 03:02:24
fcloseの定義はどこにあるのでしょうか?
glibc-2.7のソースの中には無いようなのですが…

276:デフォルトの名無しさん
08/06/15 03:07:07
libio/stdio.h

277:275
08/06/15 03:16:44
>>276
ありがとうございます!
あった!なるほど#defineされてたわけですね。
#define fclose(fp) _IO_new_fclose(fp)

で、_IO_new_fcloseをたどっていくと
最終的に__closeという関数が呼ばれているようなのですが、
今度こそ定義がglibcにはありませんでした。
ここから先はどうやって追えばよいのやら…

278:デフォルトの名無しさん
08/06/15 03:17:10
>>275
マクロになってるとかじゃないの?

279:275
08/06/15 03:22:33
すみません__closeありました。
sysdeps/march/hurd/close.c
にありました。

実は、fcloseするときにバッファをディスクに同期する
部分がどうなってるのかを追いたかったのですが、
__closeから先はどうやら単にクローズしているだけのようです。
追いなおします。

280:デフォルトの名無しさん
08/06/15 03:25:42
>>277
それはシステムコールじゃないかね。
そうだと、カーネルのソースを見る必要がある。


281:277
08/06/15 13:41:18
>>280
ありがとうございます。
Linuxのソースを見てみました。

linux/include/asm-i386/unistd.h
の中に

#define __NR_close 6

というのがあって、

linux/arch/i386/kernel/syscall_tables.S
の中のテーブルの6番の位置は

sys_close

となっていたので、sys_closeで探すと

linux/fs/open.c
の中にあって、その中で呼んでいる
filp_close
の中でflushとかやっていました。

ただ、__closeから__NR_closeのつながりがわかりませんでした。
これをどこかで#defineされているものなのでしょうか。

282:デフォルトの名無しさん
08/06/15 13:58:38
C++のスレで話すような話題か、っつーのは置いといて...
今時のOSだと、ユーザアプリがファイルをcloseした
からといって、いちいちディスクに同期は取らんと思うけど。

libcのfclose()は、fflush()を呼ぶなりして、少なくとも
ユーザアプリ(というかlibc)が握ってるデータがkernel側に渡るようにはする。
が、kernel側がダーティページをどう処理するかは、バッファキャッシュ管理の
問題になるんでは。

ぶっちゃけsyncとかがあるのはそのためでしょ。

283:デフォルトの名無しさん
08/06/15 22:44:48
class A { A(); ~A(); A(const A&); void operator=(const A&); friend class X; };
class X { class Impl; Impl* impl_; };

ユーザから見て A オブジェクトの生成と消去を X からしかできないようにしたいけど
impl_ の中で A を何らかのコンテナで管理するとき、そのコンテナは A と friend で
はないので A のコンストラクタとデストラクタを呼び出せません。A の中に実装のため
のクラスを friend として並べたくないし、実装の変更のたびに変更したくありません。

何か簡単に解決する方法はあるでしょうか?


284:デフォルトの名無しさん
08/06/15 23:10:00
>>283
class A を class X か class X::Impl の private メンバにする。

285:デフォルトの名無しさん
08/06/16 00:39:28
>>284
もちろんユーザは A の public メンバにアクセスできることが前提です。

286:デフォルトの名無しさん
08/06/16 00:57:47
>>285
A を抽象インターフェースにして実体を >284

287:デフォルトの名無しさん
08/06/16 01:12:34
template hackerさん。ヘルプミー。

template < class _T >
class C
 {
  public:
   template < class _Ta >
   void X();
 };

template < class _T >
void F()
{
C< int > obj1;
obj1.X<int>();

C< _T > obj2;
obj2.X<_T>();
}

288:デフォルトの名無しさん
08/06/16 01:13:57
めっちゃ途中で書き込んだ。さーせん。
その上のコードの、obj2.X<_T>();がコンパイルエラーで通りません。
何ででしょうか
代替案とかあるでしょうか

289:デフォルトの名無しさん
08/06/16 01:21:27
環境とエラーメッセージくらい書こうぜ

290:デフォルトの名無しさん
08/06/16 01:29:17
ったりめーだろ
class _Tの実体がない

291:デフォルトの名無しさん
08/06/16 01:29:37
じゃなかったclass _Tの定義がない

292:デフォルトの名無しさん
08/06/16 01:33:42
>>286
ああ、その手があったね。

しかも A の唯一の派生クラスを A の friend にしておけば抽象である必要もないし
X の中に入れる必要もないね。

ありがとう。

293:デフォルトの名無しさん
08/06/16 01:34:00
>>290
_Tはテンプレート引数だろ。

294:デフォルトの名無しさん
08/06/16 01:57:05
>>288
obj2.template X<_T>();
その名がテンプレートであることを示せ

>>289
この場合はいらんかも


295:デフォルトの名無しさん
08/06/16 02:02:54
>>294
>>287-288

296:デフォルトの名無しさん
08/06/16 02:21:21
>>287 予約識別子死ね。

297:デフォルトの名無しさん
08/06/16 02:25:06
>>292
> しかも A の唯一の派生クラスを A の friend にしておけば抽象である必要もないし
> X の中に入れる必要もないね。

何か変だな。一般的には、抽象でいいものに実装を混ぜる必要もないし、
スコープを無駄に広める必要もない、となりそうなもんなんだが。

まぁ望むものは得られたみたいなんで、書き込みに出てない部分の都合があっての
話ならどうでもいいけど。

298:デフォルトの名無しさん
08/06/16 07:38:23
これでいいんだよね?

class A {
public:
 virtual ~A() { }
 virtual void Foo() = 0;
};

class X {
public:
 X();
 A* NewA();
private:
 class Impl* impl_;
};

class X::Impl {
public:
 A* NewA() {
  return new AImpl;
 }

private:
 class AImpl : public A {
 public:
  virtual void Foo();
 };
};

X::X() : impl_(new Impl) { }
A* X::NewA() { return impl_->NewA(); }

299:デフォルトの名無しさん
08/06/16 12:39:10
>>297
抽象にしたくないのは単に性能のため。
Aは単純なクラスを想定しているのでそれほど実装を隠す必要はないから。
もしAの実装を隠したい場合はImpl方式にするかもしれない。
抽象クラスより優れている根拠は特にないが。

確かにAの派生はXに入れたほうが名前空間の汚染を軽減できるね。

>>298
デストラクタは private にしてユーザが削除できないようにしたい。
さらに特定のクラスにしか派生できないようにしほうが何となく安心。

300:デフォルトの名無しさん
08/06/16 12:47:35
obj2.template X<_T>();

いや本当は知らないんですけどね

301:デフォルトの名無しさん
08/06/16 23:02:51
>>294
>>300
thx。たすかりますた。thx。
>>287
解った。死ぬから_Tを使わせてくれ。

302:デフォルトの名無しさん
08/06/16 23:03:51
> _T
処理系の予約語じゃねえか・・・

303:デフォルトの名無しさん
08/06/17 21:38:29
ワラタ

304:デフォルトの名無しさん
08/06/17 23:47:32
class x について ++x と x++ を定義する場合
operator++ はどうなるのかしらぁぁぁぁぁぁぁぁ

305:デフォルトの名無しさん
08/06/17 23:53:14
++x → operator++()
x++ → operator++(int)

後者の引数はオーバーロードのためのダミー引数で、
それ以外の何かに使う物ではない。

306:デフォルトの名無しさん
08/06/17 23:55:50
X & X::operator ++ (void) ;
X X::operator ++ (int) ;

307:304
08/06/17 23:59:07
ありがとうございました。orz

308:デフォルトの名無しさん
08/06/18 07:40:42
関係無い話だけど、
テンプレート引数型で後置インクリメント使う馬鹿は氏ねと言いたい。

309:デフォルトの名無しさん
08/06/18 07:56:32
いやむしろ型特性を利用して組み込み型のときだけ後置インクリメントにするという手も

310:デフォルトの名無しさん
08/06/18 13:14:00
VC++ の2005を使用し、C++/CLIでアプリを作成しています。

ListViewに複数項目が登録されている場合、最下段での下キー押下で最上段へ、
また、最上段での上キー押下で最下段にフォーカスを移したいと思っています。

これをやるだけならキーイベントを拾って
「最下段で下キーが押された場合、フォーカス位置を0にする」
というようにすればいいのかと思ったのですが、ListViewのデフォルト機能(?)で
上下キー押下はフォーカス位置を1つずらすようになっています。

つまり、

1
2
3←フォーカス

この状態で下キーを押すと、フォーカス位置が0に戻る処理が実行された後、
フォーカス位置が1つ下にずれてしまうので

1
2←フォーカス
3

となってしまいました。

ListViewが持っているデフォルトのキーイベントを破棄できればいいのかと思ったのですが、
その捨て方も分かりませんでした・・・。

上記要件を満たす方法などがありますでしょうか?

311:デフォルトの名無しさん
08/06/18 13:39:20
スレ違い
.NETスレ行け

312:デフォルトの名無しさん
08/06/18 13:39:59
>>310
C++/CLIはC++を元にした別の独立した言語です。
なので基本的にはC++/CLIスレで質問して下さい。

しかし、言語自体でなく、
ListView(.NETコンポーネント)のことなので、
.NET総合スレか、人の多い(+構文が近い)C#スレをお勧めします。

System.Windows.Forms.ListView などは
C++/CLI, C#, VB.NETで同一のものです。

313:デフォルトの名無しさん
08/06/18 13:52:12
次スレのテンプレには、
C++/CLI関連の誘導を加えた方がよさそうだな

314:デフォルトの名無しさん
08/06/18 14:25:33
>>311、312
失礼しました
他スレにて再質問します
ありがとうございました

315:デフォルトの名無しさん
08/06/19 14:53:55
以下のプログラムで、ddd() の中のようなキャストを行ってから bbb() の中で B::f() を正しく
呼び出せるでしょうか?

struct B { void f(); };
struct D : B {};
void bbb( B* b[], int size ) { for ( int i = 0; i < size; ++i ) b[i]->f(); }
void ddd( D* d[], int size ) { bbb( static_cast<B**>( static_cast<void*>( d ) ), size ); }

316:デフォルトの名無しさん
08/06/19 15:46:32
ちょっと聞いてください。
enumハックを使ってクラスの中でSIZE_MAXという名前の定数を定義したんですよ。
そしたら、「error C2143: 構文エラー : '}' が '定数' の前にありません。」などのエラーが何個か出ました。
いろいろコメントアウトして原因を探ったら、vectorやstringなどをインクルードするとエラーが出る事がわかったんです。
で、インクルードファイルが壊れてると思い、再インストールしたんですが直らず、
結局、limits.hでSIZE_MAXという名前のマクロが定義されていたのが原因でした。
エラーメッセージに名前は出ないし、ネームスペースも無視される。
マクロって最低じゃないですか?

317:デフォルトの名無しさん
08/06/19 16:00:25
マクロのない言語に乗り換えるといいと思うよ

318:デフォルトの名無しさん
08/06/19 20:39:42
>>316
だからマクロは大文字を使うんだよ。

319:デフォルトの名無しさん
08/06/19 21:15:33
やってみて結果を述べるのが自立した大人の行動と思う。

320:デフォルトの名無しさん
08/06/19 21:15:56
319はto315

321:デフォルトの名無しさん
08/06/19 21:21:24
だから、大文字の識別名はマクロ名以外には使わないという
お約束があるんだよ。

322:デフォルトの名無しさん
08/06/19 21:46:10
>>319
すみません。特定の環境ということではなく一般的にできるかどうかです。
VC8で試したら動きます。

323:デフォルトの名無しさん
08/06/19 22:37:03
やってみた結果から刷り込まれた処理系依存な「知識」が豊富な「大人」は痛いよな

324:デフォルトの名無しさん
08/06/19 22:44:01
>>318,321
列挙型や定数に大文字使ってるのよく見かけるけどそんなお約束あるの?

325:デフォルトの名無しさん
08/06/19 22:51:45
>>324
定数もマクロだったりするし、列挙型はスコープ無いから定数の代わりに使ったりするから


326:デフォルトの名無しさん
08/06/19 23:29:25
std::wstring以外で、汎用的な文字列クラスって言うと何になるんでしょうか。
今までずっとATL::CStringWでやっていたのですが、std::wstringはいまいち不便で。
boostあたりになっちゃうんでしょうかね。

327:デフォルトの名無しさん
08/06/19 23:49:29
>>325
>定数もマクロだったりするし、
定数をマクロで書くのはよくないんじゃない?
Effective C++ 1項に書いてあるように、これこそお約束なのでは。

>列挙型はスコープ無いから定数の代わりに使ったりするから
>>316の例だって列挙型を定数がわりに使ってハマってるように見えるんだが、何か違う?


328:デフォルトの名無しさん
08/06/20 00:13:55
怪しかったらundef
CreateWindowとか

329:デフォルトの名無しさん
08/06/20 00:35:20
質問です。
あるクラスのインナークラスを他のファイルで前方宣言したいと思っているのですが
どのように宣言すればよいのでしょうか…。

以下例です。
名前空間SpaceAに定義されたクラスClassAがあったとして
ClassA内部にはInnerClassAが定義されているとします。

namespace SpaceA {
class ClassA {
public:
class InnerClassA{}
}
}

このInnerClassAを他のファイルClassB.hで前方宣言して使うことはできるのでしょうか…。

// 前方宣言
namespace SpaceA {
class ClassA;
//struct ClassA::InnerClassA; // ClassAは名前空間じゃないからエラー…どう書けばいいのか
}
using SpaceA::ClassA;

namespace SpaceB {
class ClassB {
public:
ClassB( InnerClassA* p ); // イメージ的にはこんな感じで使いたい
}
}

よろしくお願いします。

330:デフォルトの名無しさん
08/06/20 01:44:36
>>315
D* を B* としてアクセスするのは、規格の 3.10 p15 にあるエイリアスの制約に
違反するので、未定義動作。

ddd() の引数に B* の配列を似たようなキャストしてねじ込んだ場合は、上記の
制約を満たすことになるのでセーフ。

331:デフォルトの名無しさん
08/06/20 01:48:50
>>329
無理。外側の ClassA の定義が必要。 ClassA の中で class InnerClassA; としてあれば
InnerClassA の定義は必要ない。

332:デフォルトの名無しさん
08/06/20 08:20:45
>>315
>D* を B* としてアクセスするのは、規格の 3.10 p15 にあるエイリアスの制約に
>違反するので、未定義動作。

普通のアップキャストだからOKじゃないの?

333:332
08/06/20 08:34:45
332は>>315じゃなくて>>330だった。

なおModern C++ Designでは、
仮想継承でなければstatic_castによる
アップキャストは問題ないとなってた。
規格でどうなってるかは知らない。

334:332
08/06/20 09:16:06
>>330

もしかして static_cast<B**> がダメってことですか?

335:330
08/06/20 09:30:49
>>332
ごめん。まぎらわしいね。

「D* に B*& でアクセスするのは、~」ってことで、少しは伝わりやすいかな、と。

336:デフォルトの名無しさん
08/06/20 13:36:27
C++ の仕様では sizeof(B*) != sizeof(D*) の処理系もありえるのかな。

337:デフォルトの名無しさん
08/06/20 15:16:43
クラスが違うとポインタサイズも違うのか・・・?なんという

338:デフォルトの名無しさん
08/06/20 16:08:14
class XをSTL準拠にするため自作イテレータを作ろうと
operator++( X* x )みたくしたら
「クラス型パラメータがひとつもありません」と怒られました。
ハーバートシルト先生のSTL標準講座を読んでも解決法が書いてありません。
っていうか自作STLの書き方なんて載ってないし。
もうだめです。さようなら。

339:デフォルトの名無しさん
08/06/20 16:56:07
はい、さようなら。

340:デフォルトの名無しさん
08/06/20 17:37:07
using namespace std;という呪文が書いてある他人の作ったヘッダ(hoge.hh)をインクルードするのが気持ち悪かったので、

>hogehoge.hh
namespace hogehoge{
#include "hoge.hh"
};

>hogehoge.cc
#include "hogehoge.hh"
……

ってやったらhoge.hhの中でhogehoge::stdをさがしにいきやがったのが納得いかないんですが、
using namespace std;っていうのはstdをグローバルスコープにする命令じゃないんですか?

341:デフォルトの名無しさん
08/06/20 17:52:33
違うよ。
現在の名前空間から見てstd::以下にあるシンボルを現在のスコープにロードする命令だよ。

ちなみに、名前空間のなかから普通の"std"を読み込みたいなら
using namespace ::std;
とする必要がある。

342:デフォルトの名無しさん
08/06/20 18:11:09
>>338
ポインタで横着しようとしないで、イテレータ用のクラスを作る。

343:デフォルトの名無しさん
08/06/20 18:16:56
>>340
hogehoge::stdを探しにいったってことは、
hoge.hh内に namespace std {...} があるのか・・・。

using namespace std;で飽き足らず、
std空間にユーザー定義を追加するとは、不届きなヘッダだなw

とりあえず、

>hogehoge.hh
namespace hogehoge {
namespace std { using namespace ::std; } // これを追加
#include "hoge.hh"
};

しておけばおk。

344:343
08/06/20 18:54:47
あ、hoge.hhにstd系のincludeがあったら駄目か・・・。

345:デフォルトの名無しさん
08/06/20 19:01:52
>>341
うむむ、namespaceは奥深いですね。

>>343
namespace stdは見つかりませんでした。。。
あと、その行を追加してもhogehoge::stdを探しに行ってるように見えます。。。

一番簡単なのはヘッダのusing namespace std;の行を削除することなんだろうけど、
ファイルの上の方のコメントみたらcopyrightとか書いてあるし……

諦めて裸のままインクルードして使うことにします。
ありがとうございました。

346:デフォルトの名無しさん
08/06/21 13:11:25
>>344-345
hoge.hhの中にincludeがあるなら、
それを先にincludeしとけば良いんじゃね?
インクルードガードで無視されるから。
例えば #include <vector> があるなら↓のように。

#include <vector>
namespace hogehoge {
  namespace std { using namespace ::std; }
  #include "hoge.hh"
};

347:デフォルトの名無しさん
08/06/22 23:55:19
定数を指定するとき、C言語では#defineを使いましたが、
C++ではconstな変数を使え、とモノの本に書いてありました

ところで、定数がint型で何個も欲しいのですが、
列挙型の列挙子で代用するのはアリでしょうか?

348:デフォルトの名無しさん
08/06/23 00:09:47
>>347
どれくらいの個数かにもよるかもしれないけど、
列挙子で代用(?)している入門書は結構ある。

349:デフォルトの名無しさん
08/06/23 00:28:08
#define 使うなってのは、型だとか副作用だとかエラーメッセージだとかだから
enum なら問題ないと思うよ

350:デフォルトの名無しさん
08/06/23 00:30:07
配列の添え字に使いたかったんです
単なる数字より、文字のほうが読みやすいですし
ありがとうございました

351:デフォルトの名無しさん
08/06/23 00:34:33
>>347
なんで数が増えたら enum で代用するなんてことになるの?
意味が違うだろ。

352:デフォルトの名無しさん
08/06/23 00:37:28
連番なら enum だね。

353:デフォルトの名無しさん
08/06/23 00:46:05
>>351
いや、0から始まる連番なもんで

354:デフォルトの名無しさん
08/06/23 00:50:15
>>353
それなら代用じゃなくて enum が正解。逆に int const で用意するほうがありえない。

355:デフォルトの名無しさん
08/06/23 03:11:09
すみません.
ここでする質問ではないかも知れませんが.
C++でMPEG2を取り扱うプログラムを作らなくてはならなくなりました.
MPEG2を扱うにはどのようなlibraryを使わなければならないでしょうか?
またそのマニュアルが詳しく掲載しているサイトを教えてくれません?
Directshowは抜きでお願いします.

356:デフォルトの名無しさん
08/06/23 03:25:18
ffmpegでヤフれ

ただしMPEG2特許の利用ライセンスは自分でとってね!

357:デフォルトの名無しさん
08/06/23 16:44:37
VC++環境です。STLのlistについて質問です。
あるlist(Aとする)の情報をまるまる別のlist(Bとする)にassign()で写したのち、
Aのある位置を指しているイテレータをそのままBで使いたい
(Aで指していた位置にある情報を指させたい)
のですが、方法を探しても見つかりません。
アルゴリズムのfind()以外で何か方法はありますか?

358:デフォルトの名無しさん
08/06/23 17:13:09
>>357
std::distance(), std::advance()

ただ、listだとランダムアクセス出来ないから
一応それぞれO(n)で、セットでO(2n)になる。
まぁとんでもない要素数でない限り一瞬だろうけど。

359:デフォルトの名無しさん
08/06/23 17:18:01
listはアクセスするだけでもメモリの中を不規則な順序で飛び飛びするので、平均の次の要素へのアクセス速度は
要素が連続しているvectorよりも遅い。

360:デフォルトの名無しさん
08/06/23 17:24:45
>>357->>359
頭からの距離で考える発想は思いつきませんでした。
要素も少なく、実際に動かしてみても一瞬で処理できました。
ありがとうございました。

361:デフォルトの名無しさん
08/06/23 22:12:24
解決したようだが、
begin()~itとit~end()の2回に分けてコピーするのもいいな。

362:355
08/06/24 02:37:33
ffmpegをヤフりました.
MS-DOSで動くオープンソースの動画変換アプリなんですね.
ソースを見て参照方法を探れということですね?
これも方法の一つとしますが時間がかかるので,なにか他の方法はないでしょうか?

それと商用配布は考えていないのでライセンス申請の必要はありません.

363:デフォルトの名無しさん
08/06/24 03:12:10
いいえ、商用に限らず許可なく使うことは許されません。

364:デフォルトの名無しさん
08/06/24 07:35:29
特許権は、それを使ったものを製造、保管、流通することを制限することができるよ。
商用かどうかは関係ないよ。
詳しくは法務に聞こうね。

365:デフォルトの名無しさん
08/06/24 10:47:36
>>362
> MS-DOSで動くオープンソースの動画変換アプリなんですね.
違います。

> ソースを見て参照方法を探れということですね?
違います。

> これも方法の一つとしますが時間がかかるので,なにか他の方法はないでしょうか?
規格書読むより時間掛かりませんよ。

366:デフォルトの名無しさん
08/06/24 16:10:28
classのstaticメンバで、shortの配列があります。
例えば、
class hoge {
private:
 static array[100];
};
となっていて、arrayの中身を
for(int i=0; i<100; i++){
 array[i] = i*i;
}
のように初期化したいとします。
このよな作業はどの箇所で行えばいいでしょうか。

367:デフォルトの名無しさん
08/06/24 16:16:38
>>366
クラスの外で一回やっておけばよい。
main()が呼ばれる前に初期化される保証がある。

368:デフォルトの名無しさん
08/06/24 16:19:15
Singletonの問題のようにも思えるが

369:366
08/06/24 16:27:24
>>367
GCCですが、.cxxの先頭でやると怒られます。

src/hoge.cxx:24: error: expected unqualified-id before ‘for’
src/hoge.cxx:24: error: expected constructor, destructor, or type conversion before ‘<’ token
src/hoge.cxx:24: error: expected constructor, destructor, or type conversion before ‘++’ token

24: for(int i = 0; i < 100; i++){


370:デフォルトの名無しさん
08/06/24 16:28:58
#include <iostream>

class hoge {
private:
static int array[100];
static int flag;
public:
hoge() {
if (flag) {
for (int i = 0; i < 100; i++)
array[i] = i * i;
flag = 0;
}
}
void printa() const {
for (int i = 0; i < 100; i++)
std::cout << array[i] << ' ';
}
};

int hoge::flag = 1;
int hoge::array[100];

int main()
{
hoge h;

h.printa();
}


371:366
08/06/24 16:31:18
short* hoge::array = 0;

としておいて、constructorで
if(!array){
 array = new short[100];
 for(int i=0; i<100; i++){
  array[i] = i*i;
 }
}

でしょうか。それだと、いつdeleteするのでしょうか。
それとも、初期化フラグをメンバ変数に持っておいて、
それのtrue/falseでconstructorからfor文を呼び出す?

372:366
08/06/24 16:32:03
>>370
ということのようですね。
ありがとうございました。

373:デフォルトの名無しさん
08/06/24 17:22:54
どんな初期化をするかにも夜
コンストラクタとデストラクタは忘れないであげてくだちぃ

374:デフォルトの名無しさん
08/06/24 17:54:53
>>373
staticだからこの場合は無理なのよ

375:355
08/06/24 18:33:23
ffmpegのAPIを使ってMPEG2を読み込めということでしょうか?
現在mpeg2dec-0.4.1 とでどちらを使うか考えています.

両方の向き不向きについて何か教えてくれませんか?

376:デフォルトの名無しさん
08/06/24 18:49:21
C++相談室

377:355
08/06/24 19:53:12
すみません.
そうでした.完全にスレ違いになってしまいました.
去ります

378:デフォルトの名無しさん
08/06/25 00:49:33
C++って先頭からコンパイルしますよね

だから↓はコンパイルエラーになりますよね。
void main(){
int a=func(3);
}
int func(int x){
return x+5;
}

なのに、なぜ↓はコンパイルエラーにならないんでしょうか?
class cA{
public:
cA(){a=10;}
private:
int a;
};


379:デフォルトの名無しさん
08/06/25 00:50:14
C++って、単純な速さは他の言語と比較してどうなの?

380:デフォルトの名無しさん
08/06/25 00:56:45
>>378
そういう仕様に決まったから。

>>379
書き方や問題領域で当然変わってくるけど、大体Cと同じ。

381:デフォルトの名無しさん
08/06/25 00:58:44
ていうことは、C++のコンパイラは場合によっては、
読む場所を行ったり来たりしうるんですね
ありがとうございました

382:デフォルトの名無しさん
08/06/25 02:00:09
>>378
正確に述べると、クラス定義の中に関数定義を書くと、
そいつはクラス定義の終わった後に、inline付で定義されたものとして扱われるということになる。

383:デフォルトの名無しさん
08/06/25 02:15:49
クラス宣言じゃないのか。

384:デフォルトの名無しさん
08/06/25 07:37:29
定義。

385:デフォルトの名無しさん
08/06/25 07:51:00
クラス宣言って外部でメンバ関数の定義をしたりあと前方宣言
の時に使われる物?

386:デフォルトの名無しさん
08/06/25 08:26:28
クラスそのものを後方定義というやり方にも使う。

387:デフォルトの名無しさん
08/06/25 09:26:57
template<typename T> struct base{
 typename T::X test(){ return typename T::X(); }
};

struct A : base<A>{
 struct X{}
};

継承するクラスのテンプレートに継承するクラス自身を渡して、
継承するクラス内の型を基底型で使いたいのですが不可能でしょうか?

388:デフォルトの名無しさん
08/06/25 10:55:21
>>387
全く問題ない。

389:デフォルトの名無しさん
08/06/25 11:27:40
>>387
弾かれました


template<typename T> struct base{
 typename T::X test(){ return typename T::X(); } <-error C2039: 'X' : 'A' のメンバではありません。
};

struct A : base<A>{
 struct X{}
};

390:デフォルトの名無しさん
08/06/25 13:48:24
struct X {};
struct A { void add( X* x ); };

X* x = new X;
A a;
a.add( x );

A のオブジェクトは A::add() で追加した X のオブジェクトを delete する義務があります。
この場合 A::add() が失敗して例外を投げるとき A::add() は x を delete するべきでしょうか?

普通、関数が例外を投げるときその関数が何もしなかったことにするのが理想だと思いますが
delete したほうが便利な場合も多いと思うのですが。

391:デフォルトの名無しさん
08/06/25 14:02:32
すべきでないと思う
auto_ptrを使えばどうか

struct A{ void add(std::auto_ptr<X> x); };

std::auto_ptr<X> x(new X);
A a;
a.add(x);

392:デフォルトの名無しさん
08/06/25 20:30:13
>>390
391に同意。
a.add(x)に渡すxはnewしないといけないという変な制約が発生してしまうから。

393:デフォルトの名無しさん
08/06/25 20:45:33
boost の shared_ptr のコンストラクタや ptr_container の追加関数は
確か失敗したら delete される設計になってた。

394:デフォルトの名無しさん
08/06/26 02:56:30
>>390
そのインターフェースなら a.add(new X) したくなりそうだから、 delete したほうがいいと思う。


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