[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 2chのread.cgiへ]
Update time : 01/02 08:18 / Filesize : 209 KB / Number-of Response : 862
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

C++相談室 part62



1 名前:デフォルトの名無しさん mailto:sage [2008/05/27(火) 23:53:59 ]
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。

前スレ
C++相談室 part61
pc11.2ch.net/test/read.cgi/tech/1205059063/

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

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

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


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

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

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

242 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 15:33:47 ]
う〜ん、いろいろありがとう。
とりあえず最適化に任せてみます。

243 名前:デフォルトの名無しさん mailto:sage [2008/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 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 16:13:13 ]
CLIって便利だよな
特に他言語で作ったクラスライブラリがそのまま使えるお得感は感動ものだ

245 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 16:17:15 ]
>>243
ヒント:依存関係、カプセル化



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

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


248 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 18:16:41 ]
セミコロン抜けてた
CLSA * m_next; //クラスのポインター

249 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 18:32:36 ]
>>247
struct dataAの上に 「class CLSA;」を書く。

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

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

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

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

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

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

253 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 00:03:39 ]
char型のコピーはbit列をそのままコピーすると言っているのでは

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

ちょっと苦しいんで調べてみたところ、 C との互換性と合わせて見直しが
提案されているみたい。
www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2631.html
この中で 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 名前:デフォルトの名無しさん mailto:sage [2008/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 名前:デフォルトの名無しさん mailto:sage [2008/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 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 14:24:31 ]
>>255
unsigned char text[0]; はC89では認められていない。
C99から導入されたflexible array memberを使うなら、
unsigned char text[];

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

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

260 名前:255 mailto:sage [2008/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 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 20:30:10 ]
おい、お前ら、googleでソースコードの検索ができることを知ってましたか?
www.google.co.jp/codesearch

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

263 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 20:32:49 ]
どういうときにつかうん

264 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 20:34:41 ]
codeをsearchする時

265 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 20:54:24 ]
>>261-264自演乙



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

267 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 20:58:47 ]
>>266
イカですけど何か?

268 名前:デフォルトの名無しさん [2008/06/14(土) 20:59:26 ]
>>267
創価、すまんかった

269 名前:デフォルトの名無しさん mailto:sage [2008/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 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 23:16:36 ]
そんな
かわいそうな
つかいかたを
するな

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


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

273 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 02:27:52 ]
もう引数全部意図する型にキャストしちゃえよ

274 名前:デフォルトの名無しさん mailto:sage [2008/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 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 03:02:24 ]
fcloseの定義はどこにあるのでしょうか?
glibc-2.7のソースの中には無いようなのですが…



276 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 03:07:07 ]
libio/stdio.h

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

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

278 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 03:17:10 ]
>>275
マクロになってるとかじゃないの?

279 名前:275 mailto:sage [2008/06/15(日) 03:22:33 ]
すみません__closeありました。
sysdeps/march/hurd/close.c
にありました。

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

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


281 名前:277 [2008/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 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 13:58:38 ]
C++のスレで話すような話題か、っつーのは置いといて...
今時のOSだと、ユーザアプリがファイルをcloseした
からといって、いちいちディスクに同期は取らんと思うけど。

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

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

283 名前:デフォルトの名無しさん mailto:sage [2008/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 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 23:10:00 ]
>>283
class A を class X か class X::Impl の private メンバにする。

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



286 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 00:57:47 ]
>>285
A を抽象インターフェースにして実体を >284

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

289 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 01:21:27 ]
環境とエラーメッセージくらい書こうぜ

290 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 01:29:17 ]
ったりめーだろ
class _Tの実体がない

291 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 01:29:37 ]
じゃなかったclass _Tの定義がない

292 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 01:33:42 ]
>>286
ああ、その手があったね。

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

ありがとう。

293 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 01:34:00 ]
>>290
_Tはテンプレート引数だろ。

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

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


295 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 02:02:54 ]
>>294
>>287-288



296 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 02:21:21 ]
>>287 予約識別子死ね。

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

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

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

298 名前:デフォルトの名無しさん mailto:sage [2008/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 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 12:39:10 ]
>>297
抽象にしたくないのは単に性能のため。
Aは単純なクラスを想定しているのでそれほど実装を隠す必要はないから。
もしAの実装を隠したい場合はImpl方式にするかもしれない。
抽象クラスより優れている根拠は特にないが。

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

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

300 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 12:47:35 ]
obj2.template X<_T>();

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

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

302 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 23:03:51 ]
> _T
処理系の予約語じゃねえか・・・

303 名前:デフォルトの名無しさん [2008/06/17(火) 21:38:29 ]
ワラタ

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

305 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 23:53:14 ]
++x → operator++()
x++ → operator++(int)

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



306 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 23:55:50 ]
X & X::operator ++ (void) ;
X X::operator ++ (int) ;

307 名前:304 mailto:sage [2008/06/17(火) 23:59:07 ]
ありがとうございました。orz

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

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

310 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 13:14:00 ]
VC++ の2005を使用し、C++/CLIでアプリを作成しています。

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

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

つまり、

1
2
3←フォーカス

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

1
2←フォーカス
3

となってしまいました。

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

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

311 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 13:39:20 ]
スレ違い
.NETスレ行け

312 名前:デフォルトの名無しさん mailto:sage [2008/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 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 13:52:12 ]
次スレのテンプレには、
C++/CLI関連の誘導を加えた方がよさそうだな

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

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

317 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 16:00:25 ]
マクロのない言語に乗り換えるといいと思うよ

318 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 20:39:42 ]
>>316
だからマクロは大文字を使うんだよ。

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

320 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 21:15:56 ]
319はto315

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

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

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

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

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




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

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

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


328 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 00:13:55 ]
怪しかったらundef
CreateWindowとか

329 名前:デフォルトの名無しさん mailto:sage [2008/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 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 01:44:36 ]
>>315
D* を B* としてアクセスするのは、規格の 3.10 p15 にあるエイリアスの制約に
違反するので、未定義動作。

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

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

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

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

333 名前:332 mailto:sage [2008/06/20(金) 08:34:45 ]
332は>>315じゃなくて>>330だった。

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

334 名前:332 mailto:sage [2008/06/20(金) 09:16:06 ]
>>330

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

335 名前:330 mailto:sage [2008/06/20(金) 09:30:49 ]
>>332
ごめん。まぎらわしいね。

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



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

337 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 15:16:43 ]
クラスが違うとポインタサイズも違うのか・・・?なんという






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<209KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef