C++相談室 part61at TECH
C++相談室 part61 - 暇つぶし2ch237:>>182
08/03/23 23:14:58
答えは >>188 で既にでてるだろ。

まあ、10個ぐらいなら全部 friend 宣言してもいいと思うけど。

もしかして君も >>201 みたいに理解できてないやつなの? (w

238:デフォルトの名無しさん
08/03/23 23:32:29
>>188だとManager::getInstanceみたいなので取得するのと大差無いと思うが・・・

まぁ、それはともかく、>>180にfriendなどを使ってまで
制限する必要性があるのか、疑問だな。
クラスごと使わせなくするとこにfriendを使用している時点でおかしいと思う。

無名名前空間やdetails名前空間で十分なんじゃないか?


239:201
08/03/23 23:44:18
>>231
>foo() の中で X::a をアクセスしようとするからエラーになるよね。

アクセッサをManagerの方に定義することを考えていたんだけどな。
「見える」「見えない」の話じゃんくてprivateだからだろ。

>もし、C++ の private が変数を「見えなくする」なら bar() の b と同じように、
foo() は ::a を返すはずだろ?

グローバル変数よりメンバ変数を参照しにいくのは知ってます。

Managerの方に「一部のクラス」に使わせたい機能だけ、protected または public にして
一部のクラスがManagerを継承すればいい。

Manager のprivateのメンバには「一部のクラス」も参照できない。

「一部のクラス」以外にManagerクラスのインスタンスを作られるのが困る場合は
コンストラクタなどをprotectedにすればいいんでは?


「一部のクラス」に対してManagerは一つらしいので、また違ってきますが・・・・

240:デフォルトの名無しさん
08/03/23 23:58:52
これで friend いらない

-- friends.cpp
#include "A.h"
#include "B.h"

namespace
{
class Manager {};
Manger& manager();
}


void A::f() { manager().a(); }

void B::g() { manager().b(); }


241:>>182
08/03/24 00:06:26
>>238
> まぁ、それはともかく、>>180にfriendなどを使ってまで
> 制限する必要性があるのか、疑問だな。

それは、>>180 に聞いてもらわないとダメだけど、そう言う状況はありえると思うよ。

例えば、デバッグのためにマネージャの状態を直接見たりいじったりするクラスとか。
ただ 10個もあるのは、ちょっと多すぎるような気はするけどね。

>>239
頼むから、もう少し勉強してからレスしてくれ。
全然俺の言ってることが理解できてないよ。

242:デフォルトの名無しさん
08/03/24 00:08:40
で、アホなのはどっちなの?初心者なのでよく分かりません


243:デフォルトの名無しさん
08/03/24 00:51:50
>>242
やり方は色々ある。って話に落ち着けていいんじゃないのw
メイヤーズもそんなことeffective c++に書いてたでしょ。


244:デフォルトの名無しさん
08/03/24 05:56:56
>>242
「そいつの中にあるもの」の質はともかく、
「そいつの中にあるものを説明する能力」はどっこいどっこいです。

245:デフォルトの名無しさん
08/03/24 17:47:39
仮想関数を持たないクラスXとクラスYがあります。
YはXを継承しています。これらのクラスに対応する
インターフェイスのクラスIXとIYを以下のように定義しました。
しかし、コンパイルエラーでした。クラスYは抽象クラス
とみなされたようです。でも、クラスYはf()の定義も
g()の定義も持っているので抽象クラスではないように思えます。

XとYのインターフェイスを作る方法を教えて下さい。

class IX {
virtual void f() = 0;
};

class X : public IX {
void f() {}
};

class IY : public IX {
virtual void g() = 0;
};

class Y : public X, public IY {
void g() {}
};

int main()
{
Y y; // エラー(抽象クラスあるいは構造体のオブジェクトが宣言されています)
return 0;
}

246:デフォルトの名無しさん
08/03/24 17:54:22
 IX  IX
 ↑  ↑
  X  IY
  ↑↑
   Y

という継承木になっている。
X::IX::f は定義されているが、
IY::IX::f は定義されていない。

インタフェースクラスを作るなら、IX を仮想継承する必要がある。
ただ、それでも Y で f を定義する必要がある。

あと、インタフェースクラスに限らず、基底クラスには
必ず仮想デストラクタを定義するのを忘れないように。

247:デフォルトの名無しさん
08/03/24 18:14:09
>>246
ありがとうございます。
以下のように変更したらエラーが警告になりました。
この警告は無視していいような気がします。

>あと、インタフェースクラスに限らず、基底クラスには
>必ず仮想デストラクタを定義するのを忘れないように。
OKです。

class IX {
virtual void f() = 0;
};

class X : virtual public IX {
void f() {}
};

class IY : virtual public IX {
virtual void g() = 0;
};

class Y : public X, public IY {
void g() {}
};

int main()
{
Y y; // 警告('Y' : 2 つ以上のメンバが同じ名前を持っています。'X::f' から継承します。)
return 0;
}


248:デフォルトの名無しさん
08/03/24 18:50:40
Y::f では X::f と IY::f のどっちの実装を使えばいいのか分からないというもの。
まあ、今回の場合は IY::f に実装がないから X::f を使いますよという警告だけど、
Y に void f() { X::f(); } と書いておくのが無難。

249:デフォルトの名無しさん
08/03/24 19:06:35
class T
{
 T( int );
}

T *T_array = new T [100];
は出来ないじゃん?
#placement new使えってのはなしで。

std::vectorはどうやってこういうコンストラクタが引数を持ってるクラスを受け入れてるの?

250:デフォルトの名無しさん
08/03/24 19:07:20
placement newで

251:デフォルトの名無しさん
08/03/24 19:11:33
>>248
上の例では void f() 1個だけですが、実際のIXは純粋仮想関数を
22個もっています。Yに22個の関数をわざわざ定義するのはなんだか
無駄な気がするのですが。。。

252:デフォルトの名無しさん
08/03/24 19:18:29
>>251
まあ、面倒なら今のところは無視してもいいかもしれない。
コメントでも書いとこう。

253:デフォルトの名無しさん
08/03/24 19:26:44
>>241
頼むから、もう少しまともな説明してくれ。

254:デフォルトの名無しさん
08/03/24 19:31:33
>>252
わかりました。ありがとうございました。

255:デフォルトの名無しさん
08/03/24 19:31:46
friend 使うと「一部のクラス」が増えるとManagerも弄らないと駄目だな。

256:デフォルトの名無しさん
08/03/24 19:34:11
拡張性を敢えて犠牲にするなら、個別に friend するしかない。
拡張性もある程度考慮するなら基底クラス作ってそれだけ friend 。
あとは本人がどうしたいか、だな。

257:デフォルトの名無しさん
08/03/24 20:12:41
>>253
非常に初歩的な内容だし、あの説明で理解できないなら、
もうあきらめた方がいいぞ。

258:デフォルトの名無しさん
08/03/24 22:58:50
IDすら出ない板で煽り煽られ大変ですな


259:180
08/03/24 23:04:33
私の為に喧嘩しないで><。

260:デフォルトの名無しさん
08/03/24 23:59:31
struct B{
 struct P{ B *temp; }
 B( P p ){ swap( *this, *(p.temp) ); }
 operator P (){ P p; p.temp = this; return p; }
};

B Return(){ return B(); }
void Accept( B &b ){};

------------
Accept( Return() ); //Error



俺、何間違えてるの?

261:デフォルトの名無しさん
08/03/25 00:06:50
設計?

262:デフォルトの名無しさん
08/03/25 00:07:13
エラーメッセージはキチンと書く

263:デフォルトの名無しさん
08/03/25 00:09:50


264:デフォルトの名無しさん
08/03/25 00:11:00
質問の仕方

265:デフォルトの名無しさん
08/03/25 00:11:54
>>263

266:デフォルトの名無しさん
08/03/25 00:11:55
Bにデフォルトコンストラクタないからとか?

267:デフォルトの名無しさん
08/03/25 01:12:43
Humanクラスを基底クラスとするTanakaやAsouやIshikawaクラスがあるとします
Humanは抽象クラスとして用いるつもりです
このときHumanにあるstaticメソッドを一回だけ呼び出したいときってどうすればいいでしょうか?
Humanのコンストラクタで呼び出したとすると、TanakaやAsouのコンストラクタでも呼び出されますよね
static bool initのような変数をフラグとして使う方法は思いついたのですが、
もっとスマートな方法はないのでしょうか?

268:デフォルトの名無しさん
08/03/25 01:16:38
シングルトンやそれに関わるC++の実装は非常に面倒くさくて
自分で一からやろうと思うとどうしても乱雑になる。
マルチスレッドが入ってくるともっと面倒くさくなる。

269:デフォルトの名無しさん
08/03/25 01:25:21
>>260
人生、かな?

270:デフォルトの名無しさん
08/03/25 01:49:26
>>267
そのメソッドを呼び出したいのは、Human派生のオブジェクトを生成したタイミングなの?

271:267
08/03/25 02:13:35
>>270
そうですね
Human派生のオブジェクトを生成する前に呼び出しても構わないのですが

272:デフォルトの名無しさん
08/03/25 02:30:23
>>271
であれば、全てが始まる前に自分で一度だけ呼ぶのが良いと思うな。

273:デフォルトの名無しさん
08/03/25 02:31:52
>>272
それはstaticな変数をフラグにするよりダメじゃねぇかw

274:267
08/03/25 02:39:11
>>272
あぁそうか、そもそもstaticなメソッドなわけだから

int main(){
   Human::onlyOnceCalled()

みたいなかんじで
最初の方で適当に呼んでおくってのもありかもしれませんね
一回だけしか呼ばないって保証がないような気もしますが

275:デフォルトの名無しさん
08/03/25 02:49:38
>>274
必ず最初に読んでしまってよいなら、クラスにスタティックなメンバを定義して
それの初期化の中で実行させてみては?

// human.h
class Human() {
 // 中略
 class Initializer { Initializer() { onlyOnceCalled(); } };
 static Initializer init;
};

// human.cpp
Human::Initializer Human::init;

文法間違ってたらすまん

276:275
08/03/25 02:51:47
Human::Initializerのコンストラクタがpublicになってないとか、いろいろダメだorz
そこは適当におぎなって

277:267
08/03/25 03:01:51
>>275
なるほど。こういう方法もあるんですね
勉強になりました
ありがとうございました

278:デフォルトの名無しさん
08/03/25 03:05:20
保証が欲しかったのか。失礼。
initialization orderを気にするならこんな感じかな。
class Human() {
class Initializer {
Initializer() { onlyOnceCalled(); }
public:
static void Initialize() { static Initializer instance; }
};
};

これで、Initializer::Initializeを呼んだタイミングで一度だけ初期化されるようになるよ。ただしこの場合は複数スレッドとかが動き出す前に呼んでね。

279:260
08/03/25 09:32:50
ぇ?コンパイル通る?
gccだと通らないんだけど・・・

280:デフォルトの名無しさん
08/03/25 09:53:30
>>279
どこを見てそう思うんだよ・・・
指摘してくれてるだろ
>>263
>>266
あとAcceptがReturnの返す一時オブジェクトを参照してるから何とかしよう

281:デフォルトの名無しさん
08/03/25 11:14:49
>>279
まずは省略や手抜きをせずに、Bの定義を全部書け。
そして何をしたいのかはっきりさせろ。

282:260
08/03/25 16:02:29
いや、やりたいことは下のやつを知りたかっただけ。
URLリンク(ja.wikibooks.org)(Move_Constructor)
に書いてあることってnon-const referenceを受けるべきとろこに一時オブジェクトを渡せるって話だと思って、
渡してみたらコンパイラ通らないどーん。な状況。


283:デフォルトの名無しさん
08/03/25 16:44:42
>>282
これで通った
struct B{
struct P{ B *temp; };
B(){}
B(P p){ swap( *this, *(p.temp) ); }
operator P () { P p; p.temp = this; return p; }
};
B Return(){ return B(); }
void Accept( B b ){};
int main(){ Accept( Return() ); }

284:デフォルトの名無しさん
08/03/25 17:14:20
参照渡しから値渡しに変更した理由が分からん

285:デフォルトの名無しさん
08/03/25 17:18:44
抽象クラスのメソッドの定義で質問があります
抽象クラスにおいて、自分自身のクラスへのポインタの引数を取るメソッドは不可能なのでしょうか?
たとえばこういうコードです
class Human {
  void foo(Human *human) = 0;
};

コンパイルエラーになってしまいますが、なぜそうなるのか分かりません
抽象クラスだから、インスタンスを作れないので
void (Human human);
のようなメソッドはだめですよね、でもポインタならいけると思うのですが


286:デフォルトの名無しさん
08/03/25 17:20:52
B::operator P()の戻り値から構築されるBの一時オブジェクトは非const参照のAccept(B&)では受け取れないんじゃ?

287:デフォルトの名無しさん
08/03/25 17:23:26
その発送は無かったわ、thisポインタというものが(ry
virtual書いてみたらどうかな?

288:デフォルトの名無しさん
08/03/25 17:27:02
一時変数を値渡しする理由は?const参照にしない理由が分からない。

289:285
08/03/25 17:32:20
>>287
すいません元のコードではvirtualをつけてました
thisポインタは分かるのですが、この抽象クラスを継承したクラスの間でやりとりしたいことがあるのです
不勉強なので間違ってるかもしれませんが、「関連」というのをやりたいのです。
>>285の例でやるなら、一般的にはHumanクラスにHuman *hoge;みたいなポインタをメンバに持たせて関連付けするそうですが
関数の引数でやれないかと思いまして

290:デフォルトの名無しさん
08/03/25 17:35:09
>>288
const参照でもいいかもしれないけど、それ以上所有権を動かせなくならない?

291:デフォルトの名無しさん
08/03/25 17:45:20
Acceptに入ってからも譲渡するなら、
void Accept(B& b) {}
B b = Return();
Accept(b);
の方が良くないかな、それ以前に何のためのPなんだ?

292:デフォルトの名無しさん
08/03/25 17:47:47
>>285
どういう一般的例なのかちょっと分からないけど、
処理と情報を分ける実装の方が個人的にはスッキリするかな

んで、そのプログラムvirtualつけてエラーが出る理由が分からないんだけど…

293:デフォルトの名無しさん
08/03/25 17:49:24
あぁ、失礼した、operator Pはconst守るようにしてるのね
ごめん、俺が悪かった

294:292
08/03/25 18:06:34
>>292
すいませんすごく単純なクラスを作り直し、実験してみると、エラーはでませんでした。

「抽象クラスをインスタンス化することができません」というエラーメッセージだったので、
質問させていただいたのですが、おそらく他のところにエラー.の原因があると思うのでもう一度見直してみます

295:294
08/03/25 18:09:51
>>294の名前欄は>>285の間違いです

296:デフォルトの名無しさん
08/03/25 19:45:31
auto_ptrはauto_ptr_refクラスを介して対処している。
もう知っているかもしれないけど、
C++0xでは非const参照でも一時オブジェクトを受けられるようになる(右辺値参照)。

297:デフォルトの名無しさん
08/03/25 22:07:18
move semantics と rvalue reference &&

298:デフォルトの名無しさん
08/03/25 22:23:46
右辺値参照は何度もこのスレでも話されてるけど理解できん。

299:デフォルトの名無しさん
08/03/25 22:33:41
エラー出る出る言うなら、同じエラーが出る小さいプログラムを示せよ。
BやらPやらの例も、そもそもswapがないでコンパイル止まるしな。


300:デフォルトの名無しさん
08/03/25 22:34:02
右辺値及び左辺値(この二つは組)、参照の理解を固めてから見直すとよろし

301:デフォルトの名無しさん
08/03/25 22:45:08
>>298
簡単に言うと「swapでおk」ってこと。


302:260
08/03/25 23:08:35
おなにーでさーせん。swapとかごめん。あと別に必要なかったかも。
コンパイル通った。
>>283と一緒かな?

class D {
 public:
  struct Proxy { Proxy( D *d ):d_( d ){}; D *d_; };
  operator struct Proxy () { return Proxy( this ); };
  D( struct Proxy p ) {};
  void operator = ( struct Proxy p ){};
  D(){};
  D( D &rhs ){};
  void operator = ( D &rhs ){};
};

D Return() { return D(); }

int main( int, char** ){
D d = R();

return 0;
}

Accept( D &d );ってのは間違ってたかも。
ようは、
D( const D &rhs )だと、オーナーシップの移譲とかでrhsに変更加えられない。で、
D( D &rhs )だと、右辺値を渡せない。
だから、Proxyを返して、ごにょごにょする。って話なのか。

303:デフォルトの名無しさん
08/03/27 00:31:14
Cの関数ポインタにC++のClassの実体化した関数ていれられますか?
ビルドエラーが出るんですけど、そもそもそんなの出来ない?

304:デフォルトの名無しさん
08/03/27 00:54:49
>>303
できない。
関数ポインタとメンバ関数ポインタは別物。

305:デフォルトの名無しさん
08/03/27 01:38:47
>>303
Windowsのコールバック関数みたいに
こっちから引数を渡せれば、どうにでもできる。

306:デフォルトの名無しさん
08/03/27 01:54:41
>>303
sizeofを使ってポインタサイズを調べてみると、あれびっくりサイズがデカイって分るよ。
どうやっても入りません、キャストしたら情報ロストします。

307:デフォルトの名無しさん
08/03/27 02:00:59
>>306
いろいろ勘違いしてるような。

308:デフォルトの名無しさん
08/03/27 02:24:05
>>307
どこを?
具体的にどうぞ。


309:デフォルトの名無しさん
08/03/27 02:29:53
>>304-306 のうち確実に間違っているのは >>305 です、要注意。

310:デフォルトの名無しさん
08/03/27 02:49:53
面倒だからboost::functionを調べてみ >303

311:デフォルトの名無しさん
08/03/27 02:56:20
詳しく説明した方がいいかと
要するに、メンバ関数ポインタがさす関数はvirtualである事もあって
インスタンスに仕込まれた仮想テーブルを参照して、関数テーブルのうちどの位置にあるものかを取得する必要がある。
また、関数はvirtualでないケースもある、この場合仮想テーブルには関数のアドレス情報はないので、関数メンバポインタ内に情報がなければならない。
関数メンバポインタはこれら複合情報で構成された構造体となっている。


312:デフォルトの名無しさん
08/03/27 03:03:53
どこが詳しいのか


313:デフォルトの名無しさん
08/03/27 06:03:12
それなりに詳しいと思うけど、
であるがゆえに「要するに」から始まっているのは間違いだと思う。

314:デフォルトの名無しさん
08/03/27 07:26:14
>>303
関数ポインタには入れられないが、
実体とメンバ関数ポインタの対を構造体にしたものを引数に取る
ラッパ関数を通して呼ぶことはできる。
もちろん、C 側ではその構造体を直接扱うことはできないから、
void * を通すなり不完全型を利用してポインタで扱うなりする必要はあるけど。

315:デフォルトの名無しさん
08/03/27 07:39:53
>>309
>>305はCのライブラリのコールバック使うときとかの対処法の話じゃね?
大抵はvoid*のパラメータ持ってるし。

316:デフォルトの名無しさん
08/03/27 07:46:12
virtual関係無いよね。

317:デフォルトの名無しさん
08/03/27 08:15:45
そもそも、C++のclassの実体化した関数って何?実体化って何を言ってるんだ
インスタンス増えたら関数も増えるとか思ってるのだろうか、理解に苦しむ

URLリンク(www.microsoft.com)

318:303
08/03/27 08:50:26
やりたいのは複数newしたクラスからCの関数叩くんですけどその時の引数にコールバック用のCの関数ポインタがあるんです
そしてその時呼んだ実体に関数ポインタによって帰ってくるようにしたいんです


319:デフォルトの名無しさん
08/03/27 09:03:26
引数を加えて、static関数で良いんじゃ?

320:デフォルトの名無しさん
08/03/27 09:20:50
>>317
非staticメンバ関数/インスタンスメソッドの事だとみんな理解してるよ。

>>318
コールバック関数のパラメタを汎用ポインタとかで指定できるなら、そこにオブジェクトのアドレスを入れて、コールバック関数内でキャストしてメンバ関数を呼ぶ。
パラメタを指定できないなら、コールバック関数から見えるスコープの変数にオブジェクトのアドレスを入れておき、コールバック関数からメンバ関数を呼ぶ。

321:デフォルトの名無しさん
08/03/27 10:10:15
クラスの関数ポインタはthisが略されてるようなもんじゃね

322:デフォルトの名無しさん
08/03/27 10:31:11
>>317
往生際が悪い、素直に自分の知識不足でしたと認めろ

323:デフォルトの名無しさん
08/03/27 11:13:55
>>317
そのあたりは処理系依存だろ

324:デフォルトの名無しさん
08/03/27 13:09:21
static メンバ関数を C のコールバックに登録するのってよく見るし実際に
やったこともあるんだけど、ほんとは extern "C" と extern "C++" の違いで
型が遭わないはずなんだよね。

だからって対応策がわかんないし、使ったことのあるコンパイラでは全部通るから
そのまま使っちゃうんだけどさ。

325:デフォルトの名無しさん
08/03/27 13:35:22
>extern "C" と extern "C++"
"C" とかの修飾は、識別子を外部にどういう規則で公開するかという点についての指定であって、スタックフレームの作り方の指定ではない。
機種依存なので、そっちにいけと事になるが、cdeclとpascalが違えば "C" を付加しても動作しない。
C型のスタックフレームを持つ関数として登録可能な関数なら、C型のコールバックに登録する事ができるという事。
そうでないなら、コンパイルが通ったとしてもうまくいかない。

326:デフォルトの名無しさん
08/03/27 13:52:21
>>325
スタックフレームとか実装に立ち入った話はしてない。言語概念上の型が違うんだよ。

327:デフォルトの名無しさん
08/03/27 13:53:59
>>326
力いっぱいデタラメぶちかまさない

328:デフォルトの名無しさん
08/03/27 13:58:42
知識不足は許容できるが嘘吐きになってはイカンぜよ

329:デフォルトの名無しさん
08/03/27 14:03:56
>>327-328
気持ちはわかる。きっとみんなこれらは同じものとして使ってるだろうし、
動作も問題ないだろうさ。

でも規格ではエラーにならないとダメなんだよ。はっきり書いてあるから。

7.5 "Linkage specifications" p1 より
> ... Two function types with different language linkages are distinct types even
> if they are otherwise identical.

gcc でもバグ扱いだ。
URLリンク(gcc.gnu.org)

330:デフォルトの名無しさん
08/03/27 14:06:37
>>329
自分を嘘と虚栄で塗り固めるような真似はやめた方がいい、どこに突っ込み入っているのかすら理解できていないだろ。

331:デフォルトの名無しさん
08/03/27 14:10:44
静的メンバ関数はextern "C++"ではない

332:デフォルトの名無しさん
08/03/27 14:11:10
328は327に宛てたもんだと俺は思った、どうでもいいけど。

333:329
08/03/27 14:11:40
>>330
ごめん。どこに突っ込み入っているのかすら理解できてない。
どこが嘘になってるの?

334:デフォルトの名無しさん
08/03/27 14:16:32
>>331
何を根拠にそんなこと言うのか知らないけど、じゃぁ静的メンバ関数の
language linkage は "C++" 以外の何になるのさ?

335:デフォルトの名無しさん
08/03/27 16:56:26
虚言癖というか妄想癖というか・・・なんかもう病気だね(汗

336:デフォルトの名無しさん
08/03/27 17:04:34
>>334
静的メンバ関数のリンケージは内部リンケージで
その根拠は外部に公開されないから
逆にextern "C++"と同じという根拠は?

337:デフォルトの名無しさん
08/03/27 17:05:02
もうv(^・^)vの人はいないの?

338:デフォルトの名無しさん
08/03/27 17:20:53
ちゃんと勉強しろ、そんな高度な話題じゃねぇよ

339:デフォルトの名無しさん
08/03/27 18:55:41
コンストラクタの中で
配列宣言しているオブジェクトの
コンストラクタ引数を設定するにはどうしたらいいですか?

340:デフォルトの名無しさん
08/03/27 19:03:37
class Test{
Test0 objects[10];
...
};

Test::Test()
:objects[0]( 10 )
,objects[1]( 8 )
...
{
}

こんなかんじをやりたいのです。
もちろん、これではエラーです

341:デフォルトの名無しさん
08/03/27 20:36:48
>>339
できないよ。

342:デフォルトの名無しさん
08/03/27 20:51:07
解答を待っているのかもしれないが、本当にできないから。
URLリンク(www.geocities.jp)

343:デフォルトの名無しさん
08/03/27 20:57:51
どうしてもそれっぽいことがやりたいなら
vector<Test>にひとつひとつpush_back()するか
ポインタの配列にしてひとつひとつnewすればいいんでないの

344:デフォルトの名無しさん
08/03/27 21:55:56
VC++6で
for(int i=0; i<10; i++){
...
}
for(int i=0; i<10; i++){
...
}
って書いたら
iの再定義っておこられた
拡張子cppになってるのに

345:デフォルトの名無しさん
08/03/27 21:57:25
仕様です

346:デフォルトの名無しさん
08/03/27 21:58:46
1998年発売のソフトやもん。

347:デフォルトの名無しさん
08/03/27 21:59:23
>>344
びっくりするくらいみんな知ってる。
規格準拠していないんだから何も問題ない。

348:デフォルトの名無しさん
08/03/27 22:01:35
>>344
#define for if(0); else for

魔法のおまじない

349:デフォルトの名無しさん
08/03/27 22:01:59
当時は準拠してたんだよ

350:デフォルトの名無しさん
08/03/27 22:03:21
まだ規格もなかったのに何に準拠してたというのか。

351:デフォルトの名無しさん
08/03/27 22:04:00
常識。

352:デフォルトの名無しさん
08/03/27 22:29:04
>324,329
だいたい、「関数ポインタ型」それ自体にはリンケージなんか無いだろ。
それともこーゆーコードが通るコンパイラでもあるのかっつーの。
typedef static void (*hoge)();
typedef extern void (*foo)();
typedef extern "C" void (*var)();

353:デフォルトの名無しさん
08/03/27 22:36:23
typedef void (*__stdcall type)();

こういうのならたまにやる。

354:デフォルトの名無しさん
08/03/27 22:36:46
それはリンケージじゃなくて呼び出し規約

355:デフォルトの名無しさん
08/03/27 22:48:31
>>350
ARM、ISOのドラフト

356:デフォルトの名無しさん
08/03/27 22:49:53
>>355
>>344 なていたらくでか

357:デフォルトの名無しさん
08/03/27 22:58:27
>>356
forの中で定義した変数の有効範囲が
直後のループ本体に限られるようになったのは
結構遅かったのでは?D&Eでも軽く触れられていたし。

それに加え過去の互換性のためVC6はあれがデフォルトになったんだと思う。

358:デフォルトの名無しさん
08/03/27 23:27:37
昔の人が考えた仕様には、頭おかしいだろうってのがそれなりに有るからね。

359:デフォルトの名無しさん
08/03/27 23:47:27
初期のコンパイラの実装の都合もあったんじゃないかな?

最近のコンパイラで、forの変数の有効範囲が限られるようになってるのに最近気づいて思わずGJと叫んだ。


360:デフォルトの名無しさん
08/03/28 00:10:34
>>357
まあ 1998 年と言えば規格が出る年だしな。
開発期間とか考えると多少前の仕様に準じようとしてたと考えるのが妥当だけど、
その時期ならドラフトとはいえかなりな部分まで練られてると思うんだけどな。
まあ、想像でしかないので本当にギリギリになって入れられた仕様なのかもしんないけど。

VC6 はテンプレートまわりがバグ持ちすぎてかなり酷いが、
テンプレートも遅くに入った仕様だからな・・・。
new がデフォで bad_alloc 投げないとか、とにかく色々と酷い上に、
しばらく次のコンパイラが出なかったという・・・。

361:デフォルトの名無しさん
08/03/28 00:18:58
未だに古いライブラリとかで使わないといけないことが結構あるからねぇ
VS2005から入った俺としては結構苦痛
まあでもテンプレートさえなければインテリセンス反映が早いのはよい

362:デフォルトの名無しさん
08/03/28 00:36:24
VC++6.0は当時の状況を考えればしょうがないと思う

問題なのは次のコンパイラがさっさと出なかった事
お陰で変に普及しちまって、このスレでもVC++6.0でコンパイルできません的な質問が絶えない

363:デフォルトの名無しさん
08/03/28 00:38:12
全てはMSが次期製品を確実に買ってくれる為に図った陰謀。

364:デフォルトの名無しさん
08/03/28 00:53:13
MSの事情的にはむしろ逆のような?
過去のシステムヘッダに, for で宣言した変数が
その後も生きることに依存したコードがあったっていう……

365:デフォルトの名無しさん
08/03/28 00:56:00
#define for if(0) else for
のおまじないと使ったあとでATLをincludeすると
怒られるちゅーか

366:デフォルトの名無しさん
08/03/28 01:14:53
>>363
そして満を持して登場した 2002 が糞だったという罠。
そして 2003 で大きく改善されるという二重の罠。
アカデミックだと無料アップグレードできないという三重の罠。

367:デフォルトの名無しさん
08/03/28 01:16:50
#define for if(0); else for は色々やった後にやるとよろし。

368:デフォルトの名無しさん
08/03/28 01:55:57
ってかincludeする前にundefするだろ・・・

369:デフォルトの名無しさん
08/03/28 02:11:01
>>336,352
ややこしくて嫌になるが、内部とか外部とかがある「リンケージ」と
"C" とか "C++" とかがある「言語リンケージ」("language linkage") とは
別物。 >324,329 が言ってるのは言語リンケージのほうなんで、話がまるで
かみ合ってない。

370:デフォルトの名無しさん
08/03/28 03:12:43
自信満々な>>336が可哀想に見えてきちゃったよw
逆にextern "C++"と同じという根拠は?ってのが哀愁をソソル

371:デフォルトの名無しさん
08/03/28 03:26:11
>>336
素の「リンケージ」の話だとしてもおかしい。静的メンバ関数のリンケージは
ほとんど外部リンケージになる。例外は関数内のクラスのメンバの場合とかね。

372:デフォルトの名無しさん
08/03/28 03:29:08
静的メンバ関数が「外部に公開されない」ってのもおかしいな。
クラスの宣言されたスコープや、クラス内での private なり public なりに
従うだろ、常考。

373:デフォルトの名無しさん
08/03/28 03:50:38
びやーんはもうC++なんか使っていないらしい。

374:デフォルトの名無しさん
08/03/28 05:40:45
ソースは?

375:デフォルトの名無しさん
08/03/28 07:19:26
2ch

376:デフォルトの名無しさん
08/03/28 08:03:31
>>372
public, privateと内部リンケージ, 外部リンケージはまた別の話だ

377:デフォルトの名無しさん
08/03/28 08:07:53
もう何がなんだかわからないよママン

378:デフォルトの名無しさん
08/03/28 09:26:26
>>359
もともとがCへのトランスレータだった事を考えれば自然に合点が行くね。
for( int i = 0 ; .... ) { ... }
変換後
{
 int i ;
 for( i = 0 ; .... ) { ... }
}

379:デフォルトの名無しさん
08/03/28 09:47:14
>>377
C++の仕様書を見ればいいと思うお

380:デフォルトの名無しさん
08/03/28 09:57:02
>>372
リンカなどの外部に公開され得るのはクラスであって内部リンケージであるメンバが同様に公開されているように見えるのは処理系の都合

381:デフォルトの名無しさん
08/03/28 11:33:58
>>380
クラスが外部リンケージを持つときに、メンバ関数が外部リンケージを持つかどうか は処理系依存だと言っているのならそれは違うよ

382:デフォルトの名無しさん
08/03/29 03:01:24
>>377 >329,324

383:デフォルトの名無しさん
08/03/30 01:04:01
テンプレートをつかうと一気にコンパイル時間が10倍に?!

384:デフォルトの名無しさん
08/03/30 01:07:31
>>383
>>5

385:デフォルトの名無しさん
08/03/30 15:11:26
template使っても
型が1個と100個じゃ大違いだろ

386:デフォルトの名無しさん
08/03/30 15:17:08
このテンプレいつの間にか一つのレスにまとめられてたのかw

387:デフォルトの名無しさん
08/03/30 15:27:00
template <typename Questioner>
int IsCompileTimeBecomeLongerByUsingTemplate() {
return ENVIRONMENT_DEPENDENT;
}

388:デフォルトの名無しさん
08/03/30 16:25:46
テンプレート無意味過ぎる

389:デフォルトの名無しさん
08/03/30 16:28:21
>>388
質問者に応じて別の回答をするように特殊化するんだよ。

390:デフォルトの名無しさん
08/03/30 16:36:16
template<> int IsCompileTimeBecomeLongerByUsingTemplate<教えて君>()
{
 throw spoon();
}


391:デフォルトの名無しさん
08/03/30 16:59:30
匙は投げられた。

392:デフォルトの名無しさん
08/03/30 17:30:09
the biggest news of the meeting was that we voted lambda functions and closures into C++0x.

// Writing a collection to cout, in C++0x:

for_each( w.begin(), w.end(),
[]( const Widget& w ) { cout << w << " "; } );


393:デフォルトの名無しさん
08/03/30 17:59:38
スレ違い

394:デフォルトの名無しさん
08/03/31 01:28:23
LRESULT CALLBACKの関数をCLASSに所属させるにはどうすればできますか?

395:デフォルトの名無しさん
08/03/31 01:37:29
static

396:デフォルトの名無しさん
08/03/31 02:07:44
>>394
URLリンク(web.archive.org)

397:デフォルトの名無しさん
08/03/31 05:36:51
RTTIについて質問です。
RTTIありでオブジェクトファイルを生成したいが
外部libなどがRTTIを含んでいない場合は
自分側もそれにあわせてRTTIなしで組まなければ成らないのでしょうか?

398:デフォルトの名無しさん
08/03/31 10:26:48
コンパイラオプションでRTTIを使うかどうかの設定の話なら、ケースバイケース。
自分が知るVC++では、外部のオブジェクトに対してtypeidやdynamic_castをしなければ、
自プログラムがRTTI有効でも、問題なくリンクして実行できる。
逆にそうでない処理系も世の中あるかもしれない。

399:デフォルトの名無しさん
08/03/31 12:28:13
>>397
リンクでエラーが出たらオプション変えればいいんじゃないか?


400:デフォルトの名無しさん
08/03/31 17:21:40 BE:1614463687-2BP(200)
URLリンク(www.borland.co.jp)
が切れていてBorland C++ Compilerがダウンロードできないんだけど


401:デフォルトの名無しさん
08/03/31 17:25:43
>>400
普通にアクセスできるしスレ違いですさようなら

402:デフォルトの名無しさん
08/04/01 02:25:47
test

403:397
08/04/01 02:34:57
>>398
環境依存てことですかね~。

>>399
vcとのクロス開発あたりだとエラーがでてしまうのです;;

根本的になにをやりたいかというと、
シリアライズ機能を自前で実装しようと考えていまして
実装の際にRTTIのtypeidを利用して組むとらくそうなのですが・・・
ない場合はMFCやwxWidgetのようなクラス毎にマクロを仕組んで
独自の機構を作るしかないのかなって悩んでしまって・・
※boostのシリアライズという選択肢もありますが、boostが対応していない環境も考慮しました。


404:デフォルトの名無しさん
08/04/01 06:49:14
というか、例外・RTTI・CRTは、何も考えずに
DLL超えとか、コンパイラ/オプションの違うlibを混ぜるとか
するとハマるよ?

405:デフォルトの名無しさん
08/04/01 06:58:03
>>403
libのクラスをもう一度派生させたのを使ってみてはどうかな?
念のために聞くけど、そのlibをコンパイルしたコンパイラと使ってるコンパイラの種類とバージョンはあってる?


406:397
08/04/02 04:43:48
>404
こちらはそこを懸念してるんですが、出来上がったものを使うのは私ではないのでなんとも・・・

>405
バージョンのほうはあってますが、こちらでつくったモジュールがどのようなケースで使用されるか
をすべて網羅するわけにはいかないので・・
派生というかstubのようなものをproxyとして使用する感じでしょうか?

なんというか、それなりの状況でも使用に耐えうるもの、となると
結局RTTIははずさなければならないのかな、と思いました。


407:デフォルトの名無しさん
08/04/02 05:08:21
これはひどい
URLリンク(builder.japan.zdnet.com)

408:デフォルトの名無しさん
08/04/02 06:12:08
アクセスできるすべての識別子をリストアップするようなツールはないでしょうか。
class X {
 int i;
public:
 int j;
 void f() {}
};
というような場合に、
X
X::j
X::f()
みたいに出力できるとうれしいのですが……。自分で字句解析するしかないかな。

409:デフォルトの名無しさん
08/04/02 06:47:39
doxygenいろいろ設定すれば出来るんじゃね?知らないけど。

410:デフォルトの名無しさん
08/04/02 08:45:55
>>407
他で散々話題になっているんだからここでまで張らなくていいよ。

411:デフォルトの名無しさん
08/04/03 00:16:30
>>408
doxygenで可能。privateは出てこない(設定で変えられるかも)

412:デフォルトの名無しさん
08/04/05 13:46:16
extern "C"しないで作られたshared libをcから呼ぶ方法ないでしょうか?

413:デフォルトの名無しさん
08/04/05 14:19:43
マングリング名がCの識別子として使えるならいけるかもね

414:デフォルトの名無しさん
08/04/05 14:49:22
C++ で C 用のラッパ関数作るといい。

415:デフォルトの名無しさん
08/04/05 16:47:51
>>412
.defファイルをがんがって作る


416:デフォルトの名無しさん
08/04/05 20:14:21
ふつーにdlopenするとか。呼び出し規約が同じとは限らないけどw

417:デフォルトの名無しさん
08/04/07 17:03:38
gccxmlを使った他言語(pythonなど)への
インターフェース自動生成ツールが最近でてきてるけど
ちょっと複雑なコードだと自動生成に失敗するみたいだ

まだ発展途上のツールだから仕方ないのか
gccxmlに渡すオプションを考えればうまくいくのか

どうなんでしょうか?

418:デフォルトの名無しさん
08/04/07 20:28:21
Exceptional C++ を読んでて、疑問点が出てきましたので質問します。
P173~181 にかけての auto_ptr についての説明中に、

T* pt( new T(1) );
auto_ptr<T> pt( new T );
auto_ptr<T> a( source() );

↑どう見ても関数呼び出しに見えるのですが、
初期化子と解釈しないとどうも前後の説明から辻褄が合いません。
ですが、手元にある数冊の参考書を調べてもググってみても
以上のような構文は「コンストラクタ初期化リスト」以外には見あたりませんでした。
これは関数呼び出しなのでしょうか?それとも初期化子なのでしょうか?
もし、初期化子だとしたら、このような構文が出てきたときに
どのようにして見分けたら良いのでしょうか?
また、関数呼び出しのように見える初期化子の使い方についても
よろしくご教示願います。

419:デフォルトの名無しさん
08/04/07 20:34:16
まさか<T>の部分を聞いてるのか?

420:デフォルトの名無しさん
08/04/07 20:43:27
int i = 0;
int i(0);

上のふたつは等価、という話なのかな?

typename identifier(typename, typename, ...); // プロトタイプ宣言
typename identifier(arg1, arg2, ...); // 初期化
identifier(arg1, arg2, ...); // 関数呼び出し

ただし、C++では、関数宣言として解析できるものは関数宣言と見なすので、
list<int> data(istream_iterator<int>(cin), istream_iterator<int>());
は(cinの内容で初期化したlistの宣言ではなく)関数宣言になる。

421:デフォルトの名無しさん
08/04/07 21:26:48
typedef typelist< char, 1, 2, 3, bool > LIST;
なんてことは出来ないですかね?

422:デフォルトの名無しさん
08/04/07 21:32:31
boost::mpl, boost::tuple, boost::fusion辺り?

423:デフォルトの名無しさん
08/04/07 22:43:42
>>418 読むだけじゃなくていろいろ試してみたら?

424:デフォルトの名無しさん
08/04/07 23:49:20
classメンバを外部からリードオンリーに出来ませんか?
全部のメンバにゲッタを設定するのも面倒ですし


425:デフォルトの名無しさん
08/04/07 23:49:20
>>418
その本持ってるが、その部分に間違いはない。
auto_ptrのメンバ関数のインターフェース見れば疑問は無くなるはず。


426:デフォルトの名無しさん
08/04/08 00:19:52
>>424
面倒でも書く。


427:デフォルトの名無しさん
08/04/08 00:32:34
>>424
class A{
public:
int aho;
};

const A baka; //全部リードオンリーなクラス

428:デフォルトの名無しさん
08/04/08 00:46:55
>>424
必要になるまでゲッタなんて書かなきゃいい。

429:デフォルトの名無しさん
08/04/08 00:59:50
>>424
constは?

430:デフォルトの名無しさん
08/04/08 01:07:46
constなんてダサい。時代はreadonly。

431:デフォルトの名無しさん
08/04/08 01:08:06
extern "C" {
struct B : public A
{};

}
ができた. class AのデータだけにはCからアクセスできるのかも
methodは無理か?

432:デフォルトの名無しさん
08/04/08 01:25:03
extern "C" は変数と関数にしか意味がないからな。

433:デフォルトの名無しさん
08/04/08 08:03:03
>>424
class A {
int member_prv;
public:
const int & member;
A() : member(member_prv) {}
}

まあ何だ、C++にはReadOnlyなプロパティを書く構文的な補助がないから、素直にgetter書いとけ。

434:デフォルトの名無しさん
08/04/08 12:05:30
漏れはこんなマクロを書いた。

#define readonly(TYPE, ID)\
  public: TYPE ID() const { return _##ID; }\
  private: TYPE _##ID

class C {
  readonly(int, priv);
  readonly(unsigned int, b1) : 16;
  readonly(unsigned int, b2) : 16;
public:
  C() {}
};


435:デフォルトの名無しさん
08/04/08 17:57:59
キーワードtypenameの意味が分かりません。テンプレートを定義するときに
よく使われるようですが、なくても良いような気がします。例えば、
プログラミング言語C++のp.599にある bind2nd の定義のtypenameを取って
コンパイルしてみましたが、コンパイルが通って、テストコードがきちんと
動きました。typenameの存在意義を教えていただけないでしょうか。
こういう場合にtypenameがなければ困るという分かりやすい例が欲しいです。

// ----- プログラミング言語C++(p.599)より -----
template <class BinOp>
class my_binder2nd : public unary_function<BinOp::first_argument_type, BinOp::result_type> { // my_を付けて実験
protected:
BinOp op;
typename BinOp::second_argument_type arg2; // このtypenameを取ってみた。
public:
my_binder2nd(const BinOp& x, const typename BinOp::second_argument_type& v) // このtypenameも取った。
: op(x), arg2(v) {}
result_type operator()(const argument_type& x) const { return op(x, arg2); }
};

template<class BinOp, class T> my_binder2nd<BinOp> my_bind2nd(const BinOp& op, const T& v)
{
return my_binder2nd<BinOp>(op, v);

436:デフォルトの名無しさん
08/04/08 18:30:35
>>435
URLリンク(www.fides.dti.ne.jp)

437:デフォルトの名無しさん
08/04/08 18:33:46
C++FAQにありそうなネタだな

438:デフォルトの名無しさん
08/04/08 22:18:03
コンパイラの迷いを断ち切るためにあります


439:デフォルトの名無しさん
08/04/09 04:22:44
>>436
なるほど、理解できました。でもコンパイラが十分賢ければtypenameは不要だと
言えそうですね。コンパイラはテンプレートの解析時においては typename
を付けていない T::something が型かどうか分かりませんが、実際にコードを
生成するときには分かるので、本質的には曖昧さの問題はないように思えます。

440:デフォルトの名無しさん
08/04/09 08:02:13
移植性を考慮するなら付けておけばいい。

441:デフォルトの名無しさん
08/04/09 15:23:39
別のファイルで定義した変数を使うにはどうしたらいいんでしょう?
プログラムの改変を行っているのですが、前任者が作業ごとにファイルをわけています。
AAA.cppみたいなのがいっぱいあります。ヘッダファイルも同じ名前でたくさんあります。

442:デフォルトの名無しさん
08/04/09 16:03:35
ググって一番上に来たサイト。
URLリンク(7ujm.net)

内容は見てない。

443:デフォルトの名無しさん
08/04/09 18:11:09
VC++ってもうやばくないですか?
今やVBC#でもms単位で計測しないと実行速度違いがわからないぐらいですし
出来ないこともないですよね

444:デフォルトの名無しさん
08/04/09 18:34:02
>>443
場合によりけり
あと、その話題はこのスレ向きじゃない

445:デフォルトの名無しさん
08/04/09 18:54:39
>>443
んな事ないよ
OpenGL Viewerが前回のバージョンから恐らくC#になったんだと
思うが、やはり動作がもさもさする。

446:デフォルトの名無しさん
08/04/09 19:32:09
>>443
ゲームとかms単位が命取り
ms以下単位だったら考えてやる

447:デフォルトの名無しさん
08/04/09 19:34:04
μに縮まったとしてもまだでかいだろ。

448:デフォルトの名無しさん
08/04/09 19:42:54
数値計算とかやったことないんだろうなあ。

449:デフォルトの名無しさん
08/04/09 19:48:47
>>441
そういうファイル構成はC++では一般的。
その同名のヘッダーを読み込みば、十分アクセスできるはず。その前任者のソースをよく読んでC++を勉強すること。
C++はexternを滅多に使わないからね。




450:デフォルトの名無しさん
08/04/09 19:55:45
XBOX360のゲームは全部C#で書かれてるだろ

451:デフォルトの名無しさん
08/04/09 19:57:04
>>443
全然やばくない。世界はもっと広い。

452:デフォルトの名無しさん
08/04/09 20:26:56
>>439
T::something が型でも値でもコンパイルできてしまう場合は困るでしょう?
多分どちらかは間違っているんだから

453:デフォルトの名無しさん
08/04/09 21:06:55
>>450
んなわけないだろ

プロがXNAで開発してるとでも思ってるのか?

454:デフォルトの名無しさん
08/04/09 21:56:02
思ったw

455:デフォルトの名無しさん
08/04/09 22:26:41
.netフレームワークを要求する商用アプリで動きが機敏なアプリをいまだかつて見たことないな。

456:デフォルトの名無しさん
08/04/09 23:32:25
多言語からc++を呼ぶインターフェイスで
std::cout
がおかしくなる原因になってるらしくなんとかしたい
#define __streambuf なにか
にできればいいのだけど voidに置き換えるとコンパイルとおらない
何か適当なクラスでもないでしょうか?



457:デフォルトの名無しさん
08/04/09 23:38:17
ios::sync_with_stdio で解決されるような問題じゃなくて?

458:456
08/04/10 00:12:16
他言語の処理系がstdcoutをすでにリンクしているのに
さらにその処理系から呼び出すcのプログラム中でもリンクしてるのが
問題なってる可能性があるような気がしています

なので
#define __streambuf Hoge
できると多分うまくいくのではないかと

459:デフォルトの名無しさん
08/04/10 00:17:47
XNAなめんな

460:デフォルトの名無しさん
08/04/10 00:22:13
>>456
多言語から呼び出すってっ、もしかすると他言語からDLL呼び出しすることってことかな?
だったらライブラリの初期化がうまく言ってないんじゃないか?dllmainはこねこねした?


461:デフォルトの名無しさん
08/04/10 00:23:42
あと、DLLはマルチスレッドライブラリでコンパイルだよ。

462:456
08/04/10 00:24:19
>>460
正確にはlibhoge.soを呼んでます
libhoge.soがstd::stream関係をリンクしてます

463:460
08/04/10 00:27:49
linuxでしたか。>>460はwinの場合の注意事項でした。

464:デフォルトの名無しさん
08/04/10 07:50:43
>>461
MTでコンパイルしないといけない決まりでもあるの?

465:デフォルトの名無しさん
08/04/10 08:21:08
>>464
ある。
DLLをコンパイルするときはMTでする必要がある。プロジェクトの作成でDLLを選択すると自動的にマルチスレッドランタイムライブラリが選択される。
呼ぶ側はどっちでもいい。

466:デフォルトの名無しさん
08/04/10 11:49:02
>>465
何の処理系の話か知らないがVisualC++なら
シングルスレッドのランタイムの静的ライブラリをリンクしたシングルスレッド専用のDLLを普通に作れる

467:デフォルトの名無しさん
08/04/10 11:57:21
端で見てて想像した通りの食い違い方w

468:デフォルトの名無しさん
08/04/10 12:10:14
初歩的な質問で申し訳ないんだが、他言語から C++ の
ライブラリを使って問題無いはず、という保証はあるんだろうか?

あと、普通に C++ で呼び出すとかなぜしないのだろうか。
(これは状況がわからんとなんとも言えないけど)

469:デフォルトの名無しさん
08/04/10 14:18:03
operator==() の定義はクラスの中とクラスの外に置けますがどのように
使い分けるのでしょうか?

std::type_info はクラスの中でその他はクラスの外が多いのですが。


470:デフォルトの名無しさん
08/04/10 15:34:04
別にoperator==()に限らずメンバ関数は中にも外にも置けるけど。

471:デフォルトの名無しさん
08/04/10 17:04:36
ププ

472:デフォルトの名無しさん
08/04/10 17:05:09
ペペ

473:デフォルトの名無しさん
08/04/10 17:30:44
== どうするかは状況によるんでは。無理無く member にしないで
いいならそうすればいいような気がするが。中身の情報が必要な
場合に member にしてるんじゃないの?普通に生じる状況だと思うけど。

474:デフォルトの名無しさん
08/04/10 17:43:05
メンバに出来るものは中に書く。
メンバに出来ないものは外に書く。
以上。

475:デフォルトの名無しさん
08/04/10 18:05:52
c++のエラー出力の文字コードがutf-8になっているのですが、
euc-jpにする方法ありますか?
Linuxのeuc-jp環境でプログラミング行っており、
gcc version 4.1.2 です。

476:デフォルトの名無しさん
08/04/10 18:18:07
iconv

477:デフォルトの名無しさん
08/04/10 18:40:50
ロケール切り替えろとしか

478:デフォルトの名無しさん
08/04/10 19:06:32
public 関数だけで実装できる場合は非メンバーにする。
friend を使って非メンバーにすることもある。


479:デフォルトの名無しさん
08/04/10 20:50:36
式の対称性が必要なら非メンバー

480:デフォルトの名無しさん
08/04/10 20:59:53
自身への参照を返すことが期待されるか、自身を変更する場合は、メンバーにすることが漏れは多いな。
operator=, +=等はメンバに。operator==, <<, +等は非メンバ(場合によってはfriend)にしてる。


481:デフォルトの名無しさん
08/04/10 21:08:54
op == あたりの話はeffective C++に書いてなかった?
もう忘れちゃったけど。
グローバルにop ==を置くことでカプセル化が上がるとか
その話とはまた別?

482:デフォルトの名無しさん
08/04/10 21:20:10
friend はできれば避けた方が良いというの無かったっけ?

483:デフォルトの名無しさん
08/04/10 22:12:02
C++ Coding Standards の 44 には
「できるだけ非メンバーかつ非 friend の関数を書くようにしよう」
というのがありました。

484:デフォルトの名無しさん
08/04/10 22:19:02
C++の本質はやっぱプリプロセッサとテンプレートだろ・・・
オブジェクト指向なんてうんこ


485:デフォルトの名無しさん
08/04/10 23:00:41
プリプロセッサはちょっと違うだろ・・・
現実的にメタプログラミングするのには必要だけど。
個人的にはデストラクタを推すね。

2行目は同意。

486:デフォルトの名無しさん
08/04/10 23:08:04
デストラクタとはいいところをつくね。
RAII 万歳!

487:デフォルトの名無しさん
08/04/10 23:25:35
friendかな


488:デフォルトの名無しさん
08/04/10 23:58:56
>>485 == >>486 ??

489:デフォルトの名無しさん
08/04/11 00:01:31
デストラクタの価値が分からないうちは
プログラマの資格なしだぜ

490:485
08/04/11 00:03:01
>>488
ID出ない板だからどうしようも無いけど、
違うとだけ。

491:デフォルトの名無しさん
08/04/11 00:14:49
デストラクタはクリティカルセクション解除するのに使ってる。
メモリリークどころの騒ぎじゃない

492:デフォルトの名無しさん
08/04/11 00:17:31
Javaとかどーやってんだ?
デストラクタ

493:デフォルトの名無しさん
08/04/11 00:20:23
Javaはcloseとかdisposeとかメソッド作って
呼び出さないといけないんじゃなかったっけ?

494:デフォルトの名無しさん
08/04/11 00:25:56
Javaはデストラクタ勝手に作ってくれるから。
DB接続とかファイルハンドルにクリティカルセクションだの
なんでも閉じてくれる。


495:デフォルトの名無しさん
08/04/11 00:28:48
前スレから
スレリンク(tech板:496-番)

496 :デフォルトの名無しさん [sage] :2008/02/15(金) 14:44:30
  つまるところc++ではデストラクタに頼るべき。

497 :デフォルトの名無しさん [sage] :2008/02/15(金) 14:54:04
  C++はつまるところデストラクタのことだからな
  closeさせといてガベージコレクタがあるとか抜かす言語は笑えるな
  intは回収できるが巨大なファイルリソースはリークするわけだ

498 :デフォルトの名無しさん [sage] :2008/02/15(金) 15:06:22
  日本語でおk

499 :デフォルトの名無しさん [sage] :2008/02/15(金) 15:08:34
  >closeさせといてガベージコレクタがあるとか
  禿げあがる程同意。
  
  C#はusing(o1,o2,...){}があるから多少マシだけど、
  forみたいにusing用のスコープ作るから
  スコープ違いが混じるとネストして見辛くなる。
  どう考えてもc++みたいに対象の変数のスコープでDisposeした方が良いと思う。
  
  javaのtry-finally-closeに至っては論外。
  しかもcloseで例外出たらfinally内で潰さないと
  try内で発生したより重要な例外が消されるし・・・。

500 :デフォルトの名無しさん [sage] :2008/02/15(金) 16:33:04
  >どう考えてもc++みたいに対象の変数のスコープでDisposeした方が良いと思う。
  そして言語はC++/CLIへと進化するのであった、まる

496:デフォルトの名無しさん
08/04/11 00:34:08
Javaをはじめ、メジャーな言語のGCはメモリ不足しか認識しないから、
明示的にcloseしない場合、メモリに余裕があればfinalizeは呼ばれず、
DB接続も閉じられない

そしてコネクションプールのタイムアウトで死に始める業務アプリ
鳴り始めるサポートデスクの電話機達

497:デフォルトの名無しさん
08/04/11 00:39:21
まぁJavaなんてマーケット戦略で広まっただけのうんこ言語だからな・・・
プログラマと名乗るくらいならC++くらいできる頭を持って欲しい・・

498:デフォルトの名無しさん
08/04/11 00:59:54
finalize()でリソース解放なんて保険でしかないからな

499:デフォルトの名無しさん
08/04/11 01:00:32
リソース管理で似た話を読んだことある気がしてたけど思い出せた
URLリンク(mag.autumn.org)

500:デフォルトの名無しさん
08/04/11 01:00:40
でもね、C++は巨大で複雑怪奇だからね。Cを引きずってる面もあるし。
無駄を削ぎ落として細部を明確にした言語が望まれるというのもわかるよ。
それとGCの有用性とは別の話だが。

501:デフォルトの名無しさん
08/04/11 01:03:52
実はVBなんかも
リソース周りは優秀だったりする

502:デフォルトの名無しさん
08/04/11 01:26:11
continuationを明示的に扱えない言語はうんこ

503:デフォルトの名無しさん
08/04/11 01:26:35
scheme習いたてですか?

504:デフォルトの名無しさん
08/04/11 01:55:30
>>503
C++習いたてです。

505:デフォルトの名無しさん
08/04/11 07:46:34
C#のusingの使いづらさは異常
scopedとでもして識別子が入ってるブロックの最後でdisposeしてくれたほうがよかった

506:デフォルトの名無しさん
08/04/11 08:50:00
素朴な疑問です。

#include <iostream>
struct S { virtual void hoge() = 0; // 純粋仮想のみ };
struct S1 : public S { void hoge() { std::cout << "S1" << std::endl; }};
struct S2 : public S { void hoge() { std::cout << "S2" << std::endl; }};
int main()
{
 S1 s1;
 S2 s2;
 S& r1 = s1;
 S& r2 = s2;
 r1.hoge();
 r2.hoge();
 r1 = r2; // 基本クラスの参照を代入
 r1.hoge();
 r2.hoge();
 return 0;
}

VC8で上記のコードを実行すると
S1
S2
S1
S2
と表示されました。
r1 = r2;はS::operator=を呼ぶだけなので何も変わらない、と理解したのですが、
これはC++的に正しい挙動なのでしょうか?
それとも未定義でたまたまこうなっているだけなのでしょうか?

507:デフォルトの名無しさん
08/04/11 08:55:40
あ、改行を削ったらコメントをミスりました。
> struct S { virtual void hoge() = 0; // 純粋仮想のみ };

> struct S { virtual void hoge() = 0; /* 純粋仮想のみ */ };
です。

508:デフォルトの名無しさん
08/04/11 08:56:43
単純に、自動生成されたoperator=(S, S)で仮想関数テーブルが書き換わらないようになってるだけ。

509:デフォルトの名無しさん
08/04/11 08:57:18
s1, s2のうちSの部分だけがコピーされた、と解釈すればわからんでもない

510:デフォルトの名無しさん
08/04/11 09:00:15
とりあえず解決するには自分でS2 operator=(S, S)を定義すればいいように思えるが、
それはS = Sの一般的な代入に関して考えるとかなり狂っているから諦めろって言う話でっていう

511:デフォルトの名無しさん
08/04/11 12:27:47
>>498
同意。finalizeって呼ばれるとは限らないとか。ほんとに気休め程度だね。


512:デフォルトの名無しさん
08/04/11 13:29:20
>>506
代入や他オブジェクトでの初期化でvptrは変更されない。


513:デフォルトの名無しさん
08/04/11 15:56:17
class A { friend class B; int x; };
class B { class C {}; };

VC8.0 では class C から class A の x が参照できますがこれは C++ の仕様ですか?


514:デフォルトの名無しさん
08/04/11 19:00:01
Cのreadableなプログラムを自動生成するメタ言語みたいなの
ないでしょうか?
readableじゃないのならあるのですが、読めないと意味ないのです

515:デフォルトの名無しさん
08/04/12 16:01:17
具体例を。

516:デフォルトの名無しさん
08/04/12 16:08:22
まともなCソースも >>514 には、readable じゃなさそうだ...。

517:デフォルトの名無しさん
08/04/13 23:17:27
vector<int>で何個か反復子を進めたあと、
それが今何番目の要素なのかを知る関数はないですか?

518:デフォルトの名無しさん
08/04/13 23:20:51
>>517
std::distance

519:デフォルトの名無しさん
08/04/13 23:21:19
i - v.begin();

520:デフォルトの名無しさん
08/04/13 23:55:08
できました、ありがとうございます。

521:デフォルトの名無しさん
08/04/14 01:34:09
URLリンク(mag.autumn.org)
ここ読むとC++よりもJAVAのほうがリソース管理に関して
優れているように思えるんだけど

522:デフォルトの名無しさん
08/04/14 01:42:17
だから何だよ

523:デフォルトの名無しさん
08/04/14 01:46:30
優れているというかパフォーマンスを犠牲にしてリソース管理の安全性を高めたという方が近いかな。
そんな事いったらC++も保守性を犠牲にパフォーマンスを高める余地のある言語と言えるけど。
ただJavaの場合は“余地”どころかプログラマに選択をさせない完全な“切捨て”であるけどね。
だからプログラマが手段を選択できる余地の残っているC++の方が優れている。終了。

524:デフォルトの名無しさん
08/04/14 01:49:22
手段を選択する必要のある場面においては、だけどな。

525:デフォルトの名無しさん
08/04/14 02:15:33
javaってfinallyの書き方間違えると死ねるしなあ
という話が >>495 にあるよ

jdbcでoracle使ったことがある人は知ってると思うけど、
closeし損ねるとリークしてそのうち動かなくなるんだよね

これを注意深く追ってると、「なんだかCでやってんのと変わらんなあ」
と思うぜ、実際。

526:デフォルトの名無しさん
08/04/14 02:27:32
だってメモリしか管理してくれないもの


527:デフォルトの名無しさん
08/04/14 07:08:37
>521
「RAIIが発明されるまでのC++」については、Javaのほうが
リソース管理が優れていた、と云わざるを得ない、けどねぇ。

528:デフォルトの名無しさん
08/04/14 07:25:04
他のリソースも管理してくれればいいのになあ。
ファイルハンドルが足りない時には
ファイルクラスのインスタンスへのガベコレを
優先的にやってくれるとか。

529:デフォルトの名無しさん
08/04/14 10:47:50
>>527
> 「RAIIが発明されるまでのC++」

って具体的に何を指すの? RAII ってプログラミング
ポリシーだと思うんだけど。「発明」されたっていまいちピンと来ない。



530:デフォルトの名無しさん
08/04/14 11:04:02
RAII が浸透してない C++ って感じのことを言いたいんじゃないか?
未だに RAII を取り入れない C++ があるとは信じられないのかもしれないが。

531:デフォルトの名無しさん
08/04/14 12:21:55
>>528
デストラクタを活用するべき

532:デフォルトの名無しさん
08/04/14 12:25:18
javaの話だろ

533:デフォルトの名無しさん
08/04/14 12:50:09
>>527
C with class の話ですか?
C++は初期のARMがかかれた頃から散々言われていますけど。

534:デフォルトの名無しさん
08/04/14 18:05:47
>>529
強いて言えば、テンプレートがなかった頃には、
auto_ptrや(削除子付きの)boost::shared_ptrのような
汎用的なものは作りづらかったと思う。

それでも、fstreamみたいに個別に作っていく手があったはずだけど。

535:デフォルトの名無しさん
08/04/14 21:38:58
なんでそこで糞設計のstreamを持ち出すかなー

536:デフォルトの名無しさん
08/04/14 22:33:50
とりあえずデストラクタでcloseしてくれるからいいだろ。
今は糞設計かどうかなんて関係ない。

537:デフォルトの名無しさん
08/04/14 23:13:37
自分のクラスにiteratorをアタッチ
するにはどうすればよいの?

538:デフォルトの名無しさん
08/04/15 00:45:20
>>537
クラスって新しい container 作ってんの?
普通に vector とかにオブジェクト入れて iterator 使うとかいう話
じゃないんだよね?

539:デフォルトの名無しさん
08/04/15 02:36:34
>>537 アタッチの意味がわからん。

540:デフォルトの名無しさん
08/04/15 07:56:33
Rubyみたいにアタッチしたいんだけど
なんでできないの?

541:デフォルトの名無しさん
08/04/15 08:59:06
だからアタッチって何だよ

542:デフォルトの名無しさん
08/04/15 09:20:53
ウラララララーって叫ぶやつじゃね?

543:デフォルトの名無しさん
08/04/15 16:55:57
それは、アパッチ

544:デフォルトの名無しさん
08/04/15 16:56:46
>>543
叫ぶやつはジェロニモだ

545:デフォルトの名無しさん
08/04/15 17:24:27
だってオラは人間だから

546:デフォルトの名無しさん
08/04/15 21:52:48
テンプレートクラスとクラステンプレートの違いを教えてエロい人!!

547:デフォルトの名無しさん
08/04/15 21:58:18
クラステンプレートを使って作られたクラスがテンプレートクラス

548:デフォルトの名無しさん
08/04/15 22:09:23
何か詳しく書かれたサイトがあれば貼っていただきたいです。

549:デフォルトの名無しさん
08/04/15 22:14:51
お前誰だよ

550:デフォルトの名無しさん
08/04/15 22:20:43
つーか言葉にこだわってどーすんの
テンプレート勉強すりゃわかることだろうに

551:デフォルトの名無しさん
08/04/15 22:32:59
ヒントがあれば十分だろ。
自分で考えて解決する楽しさを知らないやつは(ry

552:551
08/04/15 22:33:53
>>551
誤爆しました。ごめんなさい、


553:デフォルトの名無しさん
08/04/15 22:36:31
輪講で必要なんです。
わかりにくかったので聞いてみました。

554:デフォルトの名無しさん
08/04/15 22:43:22
>>552
流れとしてはわりと的を射ている気がするw

555:デフォルトの名無しさん
08/04/15 23:01:58
テンプレートクラスはただの間違いだと思う
クラステンプレートが正しい。だってあれはテンプレートだから

クラステンプレートをテンプレートクラスというのは
鉄パイプをパイプ鉄というようなもの

556:デフォルトの名無しさん
08/04/15 23:16:18
>>555さん
わかりやすい表現ありがとうございます。

教科書には
クラステンプレートはテンプレートクラスから導出できる。
クラステンプレートは非テンプレートクラスから導出できる。
テンプレートクラスはクラステンプレートから導出できる。
非テンプレートクラスはクラステンプレートから導出できる。
と書いてあるのですが・・・

557:デフォルトの名無しさん
08/04/15 23:24:08
まずは本の名前を晒してみれ。

558:デフォルトの名無しさん
08/04/15 23:25:34
なんの哲学書だよw

559:デフォルトの名無しさん
08/04/15 23:26:56
こんにゃくゼリーに使うこんにゃくをゼリーこんにゃくって呼んでる類だろ。

560:デフォルトの名無しさん
08/04/15 23:26:59
ぐぐってでてきた。これは比較的納得できるかんじ
URLリンク(www.ed.kuki.tus.ac.jp)
クラス・テンプレート(class template)
暗黙的にまたは明示的にインスタンスを生成されるか、または特殊化されると、クラス型を作成するテンプレート。

テンプレート・クラス(template class)
クラス・テンプレート(class template)によって生成されるクラス・インスタンス。

561:デフォルトの名無しさん
08/04/16 00:01:31
ソースで出てくる順がtemplate classだから間違えやすいな

562:デフォルトの名無しさん
08/04/16 00:03:46
typename

563:デフォルトの名無しさん
08/04/16 00:49:24
STLに
boost::any相当のものってないよね?

困った困った

564:デフォルトの名無しさん
08/04/16 01:41:23
普通にboost::any使ったら?

565:デフォルトの名無しさん
08/04/16 01:51:09
vectorにデータを追加した時にメモリ確保に失敗した場合、検出する方法ってありませんか?
newでいうbad_allocの例外をキャッチするような感じ。

566:565
08/04/16 02:26:50
解決しました。orz
bad_alloc使えた...

567:デフォルトの名無しさん
08/04/16 03:21:12
>>563
無いなら作れば?
大したもんでもないっしょ。

568:デフォルトの名無しさん
08/04/16 13:24:51
あるアクションゲームをCとC++両方で作りました。
プレイする上で、まったく同じ動作をするものです。

Cでは主に構造体で、C++ではVectorで管理していました。
C++で作ったほうがプログラム実行時のメモリ消費量が多いのですが、
そんなもんでしょうか?

569:デフォルトの名無しさん
08/04/16 13:41:18
そんなもん
完全に同一ソースでもバイナリレベルでは例外処理が入ったり、実行時型判定が入ったりする

570:デフォルトの名無しさん
08/04/16 13:42:03
>>568
Vector は std::vector のこと?
そうなると構造体と std::vector とでは役割が違うので、置き換えれるわけ無いんだけど。

・・・もしかして
struct S { int a, b, c } s;
s.a = s.b + s.c;
これを
std::vector<int> s(3);
s[0] = s[1] + s[2];
にしたってこと?

まぁプログラムが違うんならメモリ消費量が違うのはあたりまえなんで、
あんまり気にしてもしょうがないと思う。同じになるはずっていう根拠でもなければ。

571:デフォルトの名無しさん
08/04/16 13:49:57
配列のことを構造体といい間違えたのではないか。

572:568
08/04/16 14:33:50
配列ですね、すみません。
消費メモリが数十MByte単位で変わってくると、さすがに気になったので質問しました。
C++の設計に改善点がまだあるような気もします。


573:デフォルトの名無しさん
08/04/16 16:51:23
数十MBって、それってC/C++以前にプログラムの構造がおかしいだろ常考

574:デフォルトの名無しさん
08/04/16 17:15:02
> C++で作ったほうがプログラム実行時のメモリ消費量が多いのですが、
これだけ読んだら、普通はもうちょっとささやかな差を想像するよね。
その想像をベースにして皆が一般的なことを回答したところで、いきなり
> 消費メモリが数十MByte単位で変わってくると、
っていう、量に関する新情報を出すっていうのは、広義の「情報小出し質問」だと思うよ。

自分だけが知っている状況を他人に説明するときは、発信する前に
「相手はこの説明に触れて、真っ先にどんなものを想像するだろうか?」
っていう思考を巡らせるべき。

で回答だけど、「構造体とvector」以外に両者のソースがどう違ってるかがわからないと、何とも言えない。
質問文に登場した要素だけで考えるなら、STLの使い方をどこかで根本的に間違えているんじゃないか
って気がするけども。

575:デフォルトの名無しさん
08/04/16 18:22:21
前方反復子のクラスはデフォルトコンストラクタが必要ですけど、
デフォルトコンストラクタで生成した反復子やそれを代入した
反復子に対する操作の結果は定義されているでしょうか?


576:デフォルトの名無しさん
08/04/16 20:42:11
URLリンク(www.asahi-net.or.jp)
このサイトを見ながらC++の基礎を勉強しているのですが、このページのデストラクタのサンプルプログラムを
VC++2008EEに打ち込んでも「消滅しました」のメッセージが出ないのですが、
これはVC++側の処理の問題でしょうか?

577:デフォルトの名無しさん
08/04/16 20:44:49
詳しく読んでないからわからんが、派生クラスで基底クラスのデストラクタが呼び出されないとかなら
virtualが抜けてるからとかそんなんじゃね?

578:デフォルトの名無しさん
08/04/16 20:51:17
まだ始めたばかりの初心者です。。
あまりを出さなくてよい、簡単な割り勘のようなのを作っているのですが、
-
#include<stdio.h>

int main(void)
{
int a,b,c;

/*計算の入力 金額*/
printf("金額を入力してください");
scanf("d%",&a);
/*人数*/
printf("人数を入力してください");
scanf("%d",&b);

/*計算と結果の表示*/
c=a/b;
printf("%d/%d=\t%d\n",a,b,c);

return 0;
}
-
これを実行させると、金額を入力してEnterキーを押した時点で変な数字が出てきてしまいます…
なにか足りない気がしますが、何処がおかしいのでしょうか…?
ご教授よろしくお願いします。

579:デフォルトの名無しさん
08/04/16 20:51:27
どのコードを書いて、どういうメッセージは出たのか、
情報が足りなさ過ぎる。

580:デフォルトの名無しさん
08/04/16 20:52:05
>>579>>576

581:デフォルトの名無しさん
08/04/16 20:53:09
>>578
d%

582:デフォルトの名無しさん
08/04/16 20:53:29
scanf("d%",&a);
打ち間違い?

583:576
08/04/16 21:15:39
>>580
スミマセン。。。
//dest_sample.cppのコードをまるっきりそのまま書いて実行したところ、
実行結果例の下2行の「消滅しました」のつく文だけ表示されません。
問題なくコンパイルできますし、上4行の「生成されました」と「呼び出されました」
の付く文は正常に表示されます。
試しに、筆者が書いたものをコピー&ペーストして実行してみましたが、
やはり「消滅しました」のつく、下2行の文が表示されません。
~Nanika(){
cout << "Nanikaのインスタンス" << datum << "が消滅しました。" << endl;
が完全に無視されているような状態です。

宜しくお願いします。

584:デフォルトの名無しさん
08/04/16 21:29:48
コンパイラは何?

585:デフォルトの名無しさん
08/04/16 21:39:59
namespaceにはまっています。
あるソースファイルのnamespaceで囲まれた関数を別のソースファイルでexternしたいのですが、
どうすればいいかわかりません。コンパイルエラーになります。
名前空間名を付けて呼び出してもだめで・・・。
aaa.cpp-----------------------------------
#include <stdio.h>

namespace hoge
{
void Func()
{
printf("HELLO\n");
return 0;
}
}
bbb.cpp------------------------------------

extern void hoge::Func(); ←コンパイルエラー

void main()
{
hoge::Func() ← コンパイルエラー
Func(); ← コンパイルエラー

return;
}
-----------------------------------------
bbb.cppからaaa.cppの名前空間が見えてないっぽいんですがこんな場合どうしたらいいのかわかりません。
ネットでも検索したのですが、複数ファイルに分ける事ができる記述はあっても
やり方が乗ってないので困ってます。どなたかお願いします。


586:デフォルトの名無しさん
08/04/16 21:41:05
namespace hoge{ extereeeen void Func(); }

587:デフォルトの名無しさん
08/04/16 21:41:27
namespace hoge {
 void Func();
}

int main()
{
 hoge::Func();
}

588:デフォルトの名無しさん
08/04/16 21:45:14
ああ、コンパイラはVC++2008EEか。

589:デフォルトの名無しさん
08/04/16 22:00:46
>>586
bbb.cppでexternする場合はコレもnamespaceで囲んであげないといけないと言うことでしょうか!?
やってみたのですがVC++6.0なせいか hogeがシンタックスエラーを起こしてます。
VC++対応していない?明日会社でやってみます。

>>587
586さんと似てるのですが、externしなくてもよいと言うことでしょうか?
これまたVC++6.0ではhogeがシンタックエラーを起こしています。
明日やってみます。

590:デフォルトの名無しさん
08/04/16 22:56:43
VC6 でも問題はないはずなんだが・・・

591:デフォルトの名無しさん
08/04/16 22:57:30
関数プロトタイプはデフォルトで extern ってのは常識だろ?

592:デフォルトの名無しさん
08/04/16 22:59:45
>>583
VC++2008でやってみたけど、ちゃんと表示されたよ。

593:デフォルトの名無しさん
08/04/16 23:09:05
ひょっとしてNanikaのインスタンスを
グローバルで生成したというオチではないだろうなw

594:デフォルトの名無しさん
08/04/16 23:12:02
外部ライブラリのデストラクタの方が後に走るから
グローバル変数にしても cout に問題はないと思う。
というか、グローバルにしても表示された。

595:デフォルトの名無しさん
08/04/17 01:48:09
#include <boost/regex.hpp>

template<typename TChar>
class TCHoge
{
public:
  typedef boost::basic_regex<TChar>  regex_type;
  static int Func(regex_type reg){ return 0; }//ok
  //static int Func(regex_type::flag_type flag){ return 0; }           // NG1
  //static int Func(boost::basic_regex<TChar>::flag_type flag){ return 0; } // NG2
  static int Func2(boost::basic_regex<char>::flag_type flag){ return 0; }   //OK
};

Window2000
Visual C++ 2005 express edition
boost 1.34.1

 NG1 のように記述したいのですが,以下のようなエラーとなってしまいます.

warning C4346: 'boost::basic_regex<charT>::flag_type' : 依存名は型ではありません。
error C2061: 構文エラー : 識別子 'flag_type'

VC6.0 では問題なかったのですが,どのように記述すれば良いでしょうか?

596:デフォルトの名無しさん
08/04/17 02:07:22
×boost::basic_regex<TChar>::flag_type
○typename boost::basic_regex<TChar>::flag_type

だっけ?あまり自信ないや

597:595
08/04/17 03:25:08
>>596 さん,有難う御座います.教えていただいた方法でうまくいきました.

これから typename をつけまくる作業に戻ります…

それでは.

598:デフォルトの名無しさん
08/04/17 03:48:20
>>575
基本的には全部未定義。唯一、デフォルトコンストラクタで初期化したイテレータに、
そうではない値を代入することができる、ってことになるみたい。
24.1p5 の "Iterators can also have singular values ..." あたりにそんなことが
書いてあって、デフォルトコンストラクタで作った Forward iterator は singular value を
持つ(ことがある)とされている。

要するに未初期化のポインタやヌルポインタと同じ扱いってことね。

599:デフォルトの名無しさん
08/04/17 07:27:26
>>597
VC6 だと逆にエラーになるから
もし VC6 でもコンパイルしたいということになりそうなら
後で切り替えられるようにマクロにしといた方がいい。

600:デフォルトの名無しさん
08/04/17 08:28:19
VC6を窓から捨てるのが正解かと
boostでもVC6は切ってるし

601:デフォルトの名無しさん
08/04/17 10:52:55
>>589
プロトタイプ宣言したヘッダファイルを作れ。
つーか、チミのやりかたではnamespaceつくらなくてもアウチなんだけど

602:デフォルトの名無しさん
08/04/17 12:52:38
stlやboostを使っていると、typedefを書く場所に悩みます。
class ClassA { HogePtr pHoge_; };
class ClassB { HogePtr pHoge_; };
この時、typedef boost::shared_ptr<Hoge> HogePtr;はどこに書くのが理にかなっているのでしょうか?
Hoge.h?それともClassA.hとClassB.h?

603:デフォルトの名無しさん
08/04/17 12:56:08
>>602
typedef しないという選択肢は無いのかね?
ほんとに HogePtr に意味があるなら Hoge.h だろうね。

604:602
08/04/17 13:00:36
>>603
すみませんtypedefしない選択肢もありました。
Hoge.hでtypedefするか、typedefしないかの2択ですね。
ありがとうございました。

605:デフォルトの名無しさん
08/04/17 21:40:19
class Hoge {
public:
typedef boost::shared_ptr<Hoge> ptr_t;
};
というのはどうですか?

606:デフォルトの名無しさん
08/04/17 23:27:03
ClassA や ClassB の実装部分を HogePtr の実体から分離するために
typedef 名をつかうってんなら、いっそ
template class <T> class ClassAImpl { typedef boost::shared_ptr<T> Ptr; ... };
で、
typedef ClassAImpl<Hoge> ClassA;
あたりまでやっちゃうのも悪くないと思うよ。

607:デフォルトの名無しさん
08/04/18 01:14:56
inline std::string Reverse( const std::string & src ){
return std::string( src.rbegin( ), std::rend( ) );
}
これくらいシンプルな感じで実装する方法ないですか?

608:デフォルトの名無しさん
08/04/18 01:21:01
ごめん誰か>>607を翻訳して

609:デフォルトの名無しさん
08/04/18 01:29:32
ようするに逆順でイテレーションしたいんだろうさ

610:デフォルトの名無しさん
08/04/18 01:32:28
実装する手間を惜しんでシンプルな設計を考えることは良いことだが、
人に説明する手間を惜しむのは(・A・)イクナイ!!

611:デフォルトの名無しさん
08/04/18 01:40:34
>>608
すいません。>>609ってことです。しかもstd::rend( )って何だよ・・・orz

当然できんだろ、って思ってたらコンパイルエラーになるんすね。
やっぱcopy使うのが一番まともでしょうか?


612:602
08/04/18 01:45:35
>>605
なるほど、それもありましたか。

>>606
ClassAとHogeの分離は考えてなかったです。
考えていたのは、
1、クラステンプレート実体化のコードが長くなるので、stlやboostはtypedefして使うものだと思っていた。
2、shared_ptrを使うという事は、2つ以上のクラス(スコープ)で型を使う事になるので、typedefを1箇所(Hoge.h)にだけ書いて、参照したほうがいいのではないか?
3、しかし、shared_ptrに入れて使うかどうかは、Hoge.hをインクルードして使う側の選択肢であって、使う側の可能性をHoge.hに書いてしまうのはどうか?
といったことで悩んでいました。

613:デフォルトの名無しさん
08/04/18 02:14:07
>>611
よくわからんが std::reverse でも使っとけ

614:デフォルトの名無しさん
08/04/18 02:24:36
世の中にはある程度の割り切りが必要な時だってあるのさ・・・

615:デフォルトの名無しさん
08/04/18 11:03:18
>>611
make_reverse_range(src) // boost::range_ex
src|reversed // pstade::oven

非標準のライブラリ使ってもいいならこんな感じで簡単に書ける

>>612
HogePtrをtemplateにして
template template parameterでboost::shared_ptr等を与える

// hoge.h
struct Hoge { ... };
template< template<typename T> class Pointer >
struct HogePtr {
 typedef Pointer<Hoge> type;
};

// client code
#include "hoge.h"
template< typename T > struct raw_pointer { typedef T *type; };
HogePtr<raw_ptr> raw;

#include <boost/shared_ptr.hpp>
HogePtr<boost::shared_ptr> shared;

これならhoge.hppで#includeしなくてもよくなる筈

616:デフォルトの名無しさん
08/04/18 13:57:34
>>615
×HogePtr<raw_ptr> raw;
○HogePtr<raw_ptr>::type::type raw;
×HogePtr<boost::shared_ptr> shared;
○HogePtr<boost::shared_ptr>::type shared;
ではなくて?

そもそもhoge.hppでshared_ptr.hppの#includeを避けるなら
// client code
Hoge* raw;
boost::shared_ptr<Hoge> shared;
でいいじゃん?

617:デフォルトの名無しさん
08/04/18 22:57:32
>>581
>>582
返信遅くなってしまいました…
そんな単純なミスだったんですね…
ありがとうございました。

618:デフォルトの名無しさん
08/04/19 15:15:17
ベースメンバ初期化で"this"を使用すると警告がでますが、
コンストラクタ内で"this"を使っても警告も何も出ないけど大丈夫なんですか?

警告が出てるのはインスタンスが生成されていることが保証されて無い状態で
そのポインタを読んでいることが原因になっていると考えているのですが、
だとすると、コンストラクタ内で使っても同じことですよね。

警告が出ないのは、そのポインタの先を使用しなければおkって事なんですかね・・。

619:デフォルトの名無しさん
08/04/19 15:20:45
コンストラクタ内ではメンバの実体は既に生成されているから問題ない
どんな値がはいってるかは知らないけどね

620:618
08/04/19 15:58:08
>>619
>>コンストラクタ内ではメンバの実体は既に生成されているから問題ない
なのに
>>どんな値がはいってるかは知らないけどね
とは?

実体は生成されているけど、thisが指しているのはどこか分からないよ
ってことですか?
それとも、実体の中身に何が入っているか分からないよってことですか?


621:デフォルトの名無しさん
08/04/19 16:00:42
ポインタの先を使用しなけりゃ大丈夫。

622:618
08/04/19 16:12:46
>>621
ってことは、コンストラクタでメンバ関数のアドレスを引き渡すのも危ないってことですよね。

623:デフォルトの名無しさん
08/04/19 16:14:00
コンストラクタ内でそのメンバ関数のアドレスを使わなければ大丈夫。

624:618
08/04/19 16:18:31
>>623
なるほど。理解しました。
どうもありがとうございました。

625:デフォルトの名無しさん
08/04/19 16:18:41
実体は生成される途中にある。
だから、this は存在する。
存在するが、その実体は完全に生成されていないので、
その実体を操作しようとすると色々な不具合が生じる。

1. メンバ変数が全て生成されている保証は無い。
  → メンバ変数に触る関数を呼ぶとヤバい。

2. 仮想関数の呼び出しが正常に働かない。
  → class B : public A { B() : c(this) { } void hoge(); C c; };
    とした時、B のコンストラクタ内から仮想関数 hoge を呼ぶと
    どんな状況であろうが B::hoge が呼ばれるが、
    C のコンストラクタ内から渡されたポインタを使って仮想関数 hoge を呼ぼうとすると
    どんな状況であろうが A::hoge が呼ばれる。
    B の基本的な初期化が済んでないので、B::hoge を呼ぶ事は非常に危険ということでそうなるのだが、
    もちろん A::hoge が呼ばれてしまう事も危険っちゃ危険だ。

626:618
08/04/19 16:37:18
ん...また混乱..

>>1. メンバ変数が全て生成されている保証は無い。
>>  → メンバ変数に触る関数を呼ぶとヤバい。
これだと、例えば,
class AAA {
public:
  // 危険?
  AAA(){
    this->value = 5;
  };
 
  // こちらにしなくてはならない?
  AAA():value( 5 ){
  };
 
  void test(){
    cout<<value<<endl;
  };
private:
  int value;
}
ということ?

627:デフォルトの名無しさん
08/04/19 16:55:31
ここで言っているのは、コンストラクタ以外のメンバ関数のことでしょ。
普通、メンバ関数は、コンストラクタによって適切に初期化済みであることを
前提にして書かれているから、
コンストラクタの途中で呼び出すのは、一般的には危険ということ。

628:デフォルトの名無しさん
08/04/19 17:18:51
GCC でやってみたら C::C 内でも B::hoge が呼ばれた。未定義なのかな?
URLリンク(kansai2channeler.hp.infoseek.co.jp)

629:デフォルトの名無しさん
08/04/19 18:02:59
vptrは初期化リストに先立って初期化されてるはずだから、
実装的には値が不定なだけだと思うけど、
未定義ではあると思うよ。

630:デフォルトの名無しさん
08/04/19 18:04:28
補足。this->nとかの値が不定って意味ね。

631:デフォルトの名無しさん
08/04/19 18:08:30
前に VC6 でやった時は仮想関数テーブルの初期化は最後だったけど、
どっちの仮想関数が呼ばれるかって仕様で決まってんのか?

632:デフォルトの名無しさん
08/04/19 18:15:06
え~うそ~!?
基底のコンストラクタから、
派生の仮想関数が呼ばれない、とかの話と勘違いしてない?

633:デフォルトの名無しさん
08/04/19 18:17:17
基底に this は流石に渡さんぜよ。

634:デフォルトの名無しさん
08/04/19 18:32:06
>>631
VC++だと__declspec(novtable)を付けたクラスでは
vtblの初期化が行われないなんて独自拡張がある。
(最派生クラスだけnovtable無しにして使う)

これ使っていないか?

635:デフォルトの名無しさん
08/04/19 19:41:56
novtableいいよねー
コード縮むし

636:デフォルトの名無しさん
08/04/19 20:55:37
    |┃三             
    |┃              
    |┃ ≡    _、_   
____.|ミ\___( <_,` )  
    |┃=___     \   
    |┃ ≡   )ATL 人 \ ガラッ

637:デフォルトの名無しさん
08/04/19 21:20:55
class Derived : Base {...}

void f(){
  Derived v;
}

this->vptr = &Base::vtbl → Base::メンバ初期化 → Base::ctor
→ this->vptr = &Derived::vtbl → Derived::メンバ初期化(定義順にctor) → Derived::ctor

Derived::dtor → Derived::メンバ破棄(定義逆順にdtor) → this->vptr = &Base::vtbl
→ Base::dtor → Base::メンバ破棄(定義逆順にdtor) → this->vptr = 不定値

こういう流れになるはず。VC6も。

638:637
08/04/19 21:28:41
表現がおかしかったので訂正。

× Base::メンバ初期化
○ Base::定義順にメンバ初期化
× Derived::メンバ初期化(定義順にctor)
○ Derived::定義順にメンバ初期化

ctorは「メンバの暗黙の初期化・初期化リストによる初期化」を含まないコンストラクタの中身。
dtorは「メンバのデストラクタ呼び出し」を含まないデストラクタの中身。

639:デフォルトの名無しさん
08/04/19 23:10:47
VCの実装を見る限りcinやcoutはextern修飾されてるみたいですが、
宣言のみの必要な定義のいらないこれらの様なものを自分でも書くとき、
一般的にどのコンパイラでも単にexternを付けておけば良いんでしょうか?

640:デフォルトの名無しさん
08/04/19 23:21:00
externが、必要がでるまでどこかで定義された実体を探す事がないという保証があるかどうか?

641:デフォルトの名無しさん
08/04/19 23:25:46
日h(ry

642:デフォルトの名無しさん
08/04/22 15:26:08
template<class T> struct A { struct B {}; };
template<class T> void f( typename A<T>::B ) {}
と定義して
f( A<int>::B() );
とすると

'void f(A<T>::B)' : テンプレート 引数を 'T' に対して減少できませんでした

というエラーが出るのですが、入れ子クラスではテンプレートの引数を推測でき
ないのでしょうか?

643:デフォルトの名無しさん
08/04/22 15:49:31
f( A<int>::B() );

f<int>( A<int>::B() );
と推測できないかってこと?

それは無理がありすぎるな。

644:デフォルトの名無しさん
08/04/22 17:09:44
逆にboost::implicit_castがこれを使っていて、
推論を抑えるため、引数の型をtypename mpl::identity<T>::typeにしている。

645:デフォルトの名無しさん
08/04/22 19:09:03
BがAのテンプレートパラメータTの値をtypedefの形で保持してそれをf側で参照するようにしてやれば可能になりそうだけど
そうするとfを関数オブジェクトにしないといけなくなってC++の暗黒面に突入する…と
本当にunk言語だな

646:デフォルトの名無しさん
08/04/23 17:10:39
何で
std::auto_ptr<char> x( new int );
はコンパイルエラーにならないんですか?


647:デフォルトの名無しさん
08/04/23 17:19:09
おまえがどんなコンパイラと、どんなSTLの実装使っているのか非常に気になる。

648:デフォルトの名無しさん
08/04/23 17:23:34
コンパイラは VC8 SP1 で STL はコンパイラ付属です。

649:デフォルトの名無しさん
08/04/23 22:11:04
VC8って2005だっけ?
2008ではエラーになったぞ。

650:デフォルトの名無しさん
08/04/24 00:38:29
8は2005

651:デフォルトの名無しさん
08/04/24 09:47:20
VC++2005Expressではエラーになった

652:デフォルトの名無しさん
08/04/24 12:12:58
VC7.1 だとエラーになりました。

Microsoft Visual Studio 2005
Version 8.0.50727.762 (SP.050727-7600)
だとなぜかエラーになりません。

もしかして C++ コンパイラはエラーを出す義務はないのかな?


653:デフォルトの名無しさん
08/04/24 13:26:29
多分それはない。
コンパイラのバグか、誰かがヘッダ書き換えちゃったとか。

654:デフォルトの名無しさん
08/04/24 15:07:19
デバッガで追いかけたら new int が一旦 std::auto_ptr_ref<char> に
変換されてから std::auto_ptr<char> に変換されていました。
std::auto_ptr_ref<T> は void* 型でポインタを記憶しているので
int 型は消えていました。
memory ヘッダーを確かめると確かにエラーが出ないはずです。
この動作は std::auto_ptr の仕様でしょうか?


655:デフォルトの名無しさん
08/04/24 15:34:39
これと同じみたいだね
URLリンク(connect.microsoft.com)

656:デフォルトの名無しさん
08/04/24 15:45:29
いまだに信じられんな。もうすでにVC8なんて使っていないんだが、
それほど悪いコンパイラとSTLじゃなかったはずだが。

とりあえず>>654の話から想像すると、
rvalueとlvalueの境を越えるための、あまり汎用的に使い道のない、
汚いトリックを使ってauto_ptrを実装しているが(オーバーロードとtemplate argument deductionのわずかな違いを利用するやつ)
普通に使う際にも、そのトリックが働いてしまうって事かな。
STLの実装の問題っぽいかなぁ。
ふつうauto_ptr_refのメンバをvoid *にしなければならない理由はないよな。


657:デフォルトの名無しさん
08/04/24 15:48:53
>>655
あ、>>656に加えて、auto_ptr_refのコンストラクタがexplicitじゃないのか。
だめじゃん、P.J. Plaugerさん。

658:デフォルトの名無しさん
08/04/24 19:51:53
失礼
リソースの 切り離し / 復元 を実行するメソッドの命名に困っているのですが
この意味に近くて使いやすい単語のペアはありませんかね?
機能的に必ず対になるものです。

候補としては
[Detach / Restore] Detach の対義語は Attach だしな
[Detach / Attach] Attach は「復元」では無い気がする
[Destruction / Resotre] Destが長い
[Destroy / Restore] Destory は Create のペアとして使ってきたので控えたい
ですが、どうも腑に落ちません。

659:デフォルトの名無しさん
08/04/24 19:58:10
日本語の「切り離し」と「復元」はそもそも対義語じゃないよね・・・
切り離しとその反対なら、Detach / Attach だろうし、
復元とその反対なら、Save / Restore だろう。

Destruction なんて破壊しちゃうわけでさ、英語以前に日本語の
「切り離し」「復元」ってのがそもそも違うんじゃないか?

660:658
08/04/24 20:08:51
>> 659
> 英語以前に日本語の「切り離し」「復元」ってのがそもそも違うんじゃないか?
うーむ・・仰るとおりですね

切り離しを実行すると 消失 という状態になる処理だったので
それを元に戻す意味で 復元 と考えていたのですが
もう少し考え直してみます。 ありがとうございました

661:デフォルトの名無しさん
08/04/24 20:12:44
漏れはホンちゃんの処理の準備のためのナニにはPrepareXXXを結構使うな。
オフスクリーンビットマップやら何やらの準備とか。

662:デフォルトの名無しさん
08/04/24 21:22:36
release / acquire

663:デフォルトの名無しさん
08/04/24 22:20:14
>>660
Disconnect / ReConnect とか、Detach / ReAttach とかは?

664:658
08/04/24 22:43:04
>>661
Prepare
今回は使いそうに無いけど、ひとつ賢くなりました

>>662
そういえば DirectInput に Acquire / UnAcquire (だったかな)ってのがありますね
これ良いかも

>>663
Disconnect / ReConnect
接続とはちょっと違うんですわ

ありがとうございました
スマートに命名出来るように、もうすこし設計から見直すことにします

665:デフォルトの名無しさん
08/04/24 22:50:04
template <template<class> class T>
このようなテンプレートテンプレートパラメータが
なぜこんな書き方ができるのか今一理解できません。
誰か上手いこと説明してください

666:デフォルトの名無しさん
08/04/24 22:59:29
なぜ出来るのかって、そりゃ出来るように言語仕様を改定して
コンパイラが対応したからだろ・・・

667:デフォルトの名無しさん
08/04/24 23:34:09
class X を渡せる奴は
template <class X> と書くんだから
template <class A> class T を渡せる奴は
template <template <class A> class T> と書けるようにするのが自然だろう。
むしろ他にどんな書き方があるのかと問いたい。

668:デフォルトの名無しさん
08/04/24 23:54:08
>>667
あぁ納得。
<template <class A>

最初の例だとAの部分が無かったので混乱してました

669:デフォルトの名無しさん
08/04/25 20:13:29
std::exception のメソッドの例外指定はいつの間にかなくなってしまったんですか?
URLリンク(msdn2.microsoft.com)(VS.80).aspx
を見るのすべてのメソッドに例外指定がないんですけど。
今まで std::exception が例外を投げないことを前提にプログラムを作ってきたんですが。



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