C++相談室 part60

このエントリーをはてなブックマークに追加
496デフォルトの名無しさん
つまるところc++ではデストラクタに頼るべき。
497デフォルトの名無しさん:2008/02/15(金) 14:54:04
C++はつまるところデストラクタのことだからな
closeさせといてガベージコレクタがあるとか抜かす言語は笑えるな
intは回収できるが巨大なファイルリソースはリークするわけだ
498デフォルトの名無しさん:2008/02/15(金) 15:06:22
日本語でおk
499デフォルトの名無しさん:2008/02/15(金) 15:08:34
>closeさせといてガベージコレクタがあるとか
禿げあがる程同意。

C#はusing(o1,o2,...){}があるから多少マシだけど、
forみたいにusing用のスコープ作るから
スコープ違いが混じるとネストして見辛くなる。
どう考えてもc++みたいに対象の変数のスコープでDisposeした方が良いと思う。

javaのtry-finally-closeに至っては論外。
しかもcloseで例外出たらfinally内で潰さないと
try内で発生したより重要な例外が消されるし・・・。
500デフォルトの名無しさん:2008/02/15(金) 16:33:04
>どう考えてもc++みたいに対象の変数のスコープでDisposeした方が良いと思う。
そして言語はC++/CLIへと進化するのであった、まる
501デフォルトの名無しさん:2008/02/15(金) 18:29:14
using Hoge hoge = new Hoge();

とか

Hoge hoge();

とかと書かせるようにすれば良かったのにね。C# も。
502デフォルトの名無しさん:2008/02/15(金) 21:28:46
>>469
比較関数が例外を投げないんだったら、比較の順序ごとに
std::set<Base *, Compare>を用意して挿入関数を注意深く書けばいい。
multisetにすると削除のとき最悪O(N)の時間がかかるから、
比較関数にポインタの比較を入れてsetで扱う。
比較関数が例外を投げる場合、同じ方法だと削除関数が
例外を投げることになって相当扱いにくくなる。
OpenBSDのtree.hみたいのを使って侵入型コンテナにするのが現実解かな。
503デフォルトの名無しさん:2008/02/15(金) 22:59:54
無名名前空間ってちゃんと働く?
vc8で

// hoge.hpp
namespace
{
class A
{
public:
A() {}
};
}

// main.cpp
#include "hoge.hpp"

int main()
{
A a;
}

でmain.cppからAにアクセスできてしまうけど。
なんか理解がおかしい?
504デフォルトの名無しさん:2008/02/15(金) 23:00:29
インクルードしたらアクセスできて当然だろう・・・
505デフォルトの名無しさん:2008/02/15(金) 23:11:19
無名名前空間ないのクラスは同一ファイルのものからじゃないとアクセス
できないってみたけど。
というかmain自体が無名名前空間で定義さてれいてAが見えるってことか?
506デフォルトの名無しさん:2008/02/15(金) 23:13:10
>>505
同一ファイルじゃなくて同一コンパイル単位
インクルードしてたら同じコンパイル単位に含まれるよ
507デフォルトの名無しさん:2008/02/15(金) 23:14:42
#includeの行を消して、
代わりに.hppの中身全体をその場所にコピペしてみろ。
#includeとはそういうことだろ?
508デフォルトの名無しさん:2008/02/15(金) 23:15:05
>>505 どこでそんな嘘みたんだ?晒してくれ。
509デフォルトの名無しさん:2008/02/15(金) 23:22:06
>>506
なら無名名前空間って使い道あるの?
これって#includeするヘッダ内の公開したくない部分を隠蔽する為のものかと思ったけどちがうのか。

>>508
http://wisdom.sakura.ne.jp/programming/cpp/cpp38.html
(抜粋)無名名前空間にアクセスできるのは同一ファイルのみです
510デフォルトの名無しさん:2008/02/15(金) 23:27:38
>>509
要はstatic変数の代用だ
Cではグローバル変数が他のコンパイル単位とぶつからないようにstatic変数ってものがあったが、
static構造体とかstatic typedefといったものはなかった
C++では無名名前空間がそういった役割を果たす
もちろん従来のstatic変数も残ってはいるが
511デフォルトの名無しさん:2008/02/15(金) 23:33:16
>>509
不正確な記事だな。著者に連絡しとくといいよ。
512デフォルトの名無しさん:2008/02/15(金) 23:38:19
>>511
コンパイラはプリプロセッサの処理の後に動くから、
そういう風に考えれば同一ファイルのみと考えていいんじゃね
513デフォルトの名無しさん:2008/02/15(金) 23:43:47
>>509
a.cppとb.cppがそれぞれコンパイル単位内で使うために
class Foo {
    void f();
};
void Foo::f() { ... }
のように定義すると、リンクのときにFoo:f()が衝突してしまう。
typedefや構造体の定義そのものはコンパイル単位内で完結しているから、
Cの場合は関数、変数にstaticを付けるだけで衝突を防げたけど、
C++の場合普通の関数、変数の他にクラスのメンバ関数やstaticメンバ変数があるから、
それらがリンク時に衝突しないように無名名前空間が考案された。
514デフォルトの名無しさん:2008/02/16(土) 04:10:53
「MOJO」ってのはただ単に一時オブジェクトを移動させるためのもので、
「swapで交換」とはまた別?

ぁー理解できんorz
515デフォルトの名無しさん:2008/02/16(土) 08:53:40
C/C++でプリプロセッサ命令以外でファイル単位と言ったら、
それはつまりコンパイル単位のこと。
プリプロセスとコンパイルは分けて考えないと駄目だよ。

複数のファイルを扱うのはプリプロセスとリンク。
コンパイルは(結合、加工後の)単一ファイルしか扱わない。
516デフォルトの名無しさん:2008/02/16(土) 09:36:29
>>514
move semanticsの汎用的な実装方法のとして
「デフォルトコンストラクト直後のオブジェクトとswap」がある。

でもauto_ptrみたいにswapでなく、メンバをNULLにするような方法もある。
MOJOはswapで移動させるとか限らない。

・・・って感じじゃない?。俺もMOJO詳しくないけどw
517デフォルトの名無しさん:2008/02/16(土) 09:41:16
× とか限らない
○ とは限らない
518デフォルトの名無しさん:2008/02/16(土) 09:59:32
>>512,515
そんなんだから >505 みたいな勘違いするんだよ。
入門用の記事なんだから、読み手がコンパイルとプリプロセスを
分けて考えてるとも期待できないだろうし。
519デフォルトの名無しさん:2008/02/16(土) 10:14:35
>>518
その意見は一応理解出来るけど、件のサイトには

http://wisdom.sakura.ne.jp/programming/cpp/
>C++入門の読者はC言語経験者であることを想定しています

とある。加えて、namespaceやtemplateなどより、
c++識別子のスコープ・マクロ定義スコープ・#includeの動作を
理解するのが先だと思う。
520デフォルトの名無しさん:2008/02/16(土) 10:35:16
>>519
だから何?「ファイル」と不正確な記述にしておいたほうがいい理由でもあるの?
521デフォルトの名無しさん:2008/02/16(土) 10:47:33
>>520
コンパイル単位という専門用語はあまり知られていない。
Cを知っている人の間ではファイルと呼んだ方が通りがいい。
あと、日本語では「〜単位で」が「〜ごとに」という
意味になる場合があって、
522デフォルトの名無しさん:2008/02/16(土) 10:48:01
「しておいたほうがいい理由」は無い。
しかし、C言語経験者を想定してるなら
「不正確だから修正が必要」という程のことでも無いと俺は思った。

その記事はstaticとexternを引き合いに出してるし、
それらは(特にC言語で)ファイルスコープと呼ばれる上に、
モロ翻訳単位のことだから。
523522:2008/02/16(土) 10:52:15
何か521と繋がってるように見えるから補足、
>>519==>>522です。
524デフォルトの名無しさん:2008/02/16(土) 11:10:01
だれも修正が必要なんて言ってないんだよ。
525デフォルトの名無しさん:2008/02/16(土) 11:14:18
C/C++にはコンパイル単位って用語がある。
あまり知られてないとか、ファイルの方が通りがいいとかどうでもいい。
それ以上は自分のブログででも主張したらいい。
526デフォルトの名無しさん:2008/02/16(土) 11:14:27
>>511見たら普通そう受け取るだろ
527デフォルトの名無しさん:2008/02/16(土) 11:17:24
>>526>>524宛て
528デフォルトの名無しさん:2008/02/16(土) 11:26:53
そうだね
529デフォルトの名無しさん:2008/02/16(土) 11:31:39
「連絡しとくといいとは言ったが、修正が必要とは言ってない」
っていう、二次成長期の真ん中へんに居る子みたいな言い逃れが来ると思うよ。
530デフォルトの名無しさん:2008/02/16(土) 11:31:41
>>525
ブログも2chのレスも大して変わらんよ。
「著者に連絡しとくといい」なんてレスに比べれば
個人的な主張なんてかわいいもんだろ。

というか、「どうでもいい」なんて反論?は止めた方がいいかと。
531デフォルトの名無しさん:2008/02/16(土) 11:35:48
>>521 専門用語ではあってもstandardで使われているので
重要だと思う。

おれも100%知ってるわけではないけど。

翻訳単位というのはstandardに従えば必ずしも
ファイルである必要はない。たまたま現存する実装ではそうな
っているものがほとんどであるということに過ぎない。
別にヘッダをローカルファイルではなく、データベース、ネットワーク
経由で何らかのconfigurationで展開してもstandard準拠といえる。
上にも書いてる人がいるけど翻訳単位とはプリプロセス
(マクロ、ヘッダの展開etc)終了後のエンティティを指す。
リンケージの話は翻訳単位に対して行うものだと思っている。
実際このくらいは知ってないと理解が難しくなる本もある。
カーニハンやジョスティスの本にも頻繁に出てくる。
532デフォルトの名無しさん:2008/02/16(土) 11:39:47
著者本人以外が「修正の必要はない」と繰り返し主張する意味がわからない。
もしかして本人なのかもしれないけど。
533デフォルトの名無しさん:2008/02/16(土) 12:03:38
>>509が明らかに勉強不足で理解不足だからだろ。
著者のせいにしたければ勝手に連絡すればいい。
別に止めんよ。
534デフォルトの名無しさん:2008/02/16(土) 12:04:00
それはつまり、他人の「問題」を2chに書き込むのはおかしくないけど、
「問題の無さ」を2chに書き込むのはおかしい、ということ?
俺にはその感性のほうが意味わからないかも。
Xへの突っ込みが変なせいで、X以外の人間に突っ込まれるなんて、よくあることじゃん。

あと、「繰り返し」っていうのは多分、さりげなく「必死だな」って言いたくて書いてるんだと思うけど、
これは単に、「修正が必要だ」っていう意見の子がまず「繰り返し」書き込んでいるから、
それへの反応も複数回になって「繰り返し」になっているだけだろう。
535デフォルトの名無しさん:2008/02/16(土) 12:08:19
>>532
「不正確」に対する反論がそんなに不思議?

こちらは一応根拠を示しているつもりなんだが、
それに対し、根拠も書かずに件の説明が間違っている前提なのが、
むしろ俺は不思議に思うんだけど・・・。
536デフォルトの名無しさん:2008/02/16(土) 12:12:29
件の入門記事にある不正確な記述を読んで誤解した人が少なくとも
一人いたのは事実。それを著者が知れば、修正するかもしれないし
>512,533 のように判断して修正しないかもしれない。それは著者の自由。
修正が必要だという主張も不要だという主張も同じぐらいに的はずれ。
537デフォルトの名無しさん:2008/02/16(土) 12:12:42
>>533
509が見るサイトを間違えてる気はするよな。
普通のc++入門サイトとか見た方が良いだろうから。
538デフォルトの名無しさん:2008/02/16(土) 12:12:57
ところで、ヘッダファイルのみで通じる宣言ってやりたいよなあ。
539デフォルトの名無しさん:2008/02/16(土) 12:15:34
>>536
上から目線を楽しみたいのはわかったけど、ちょっと変。
「修正が必要だという主張も不要だという主張も同じぐらいに的はずれ」という箇所から察するに、
この件についてどっちでもない立場がある、という前提で言ってるんだよね?
なのに、「修正が必要だという強弁に反論した」だけで、それを「不要だという意見」に括るのはおかしいよ。
右翼の意見に反論したら即左翼かよ、みたいな。
540デフォルトの名無しさん:2008/02/16(土) 12:16:03
>>535
不正確だというのに反論するなら、件の記事の「ファイル」という記述が正確だ
ということになるが、そうじゃないだろ?
ファイルと翻訳単位では確実に意味が違う。
541デフォルトの名無しさん:2008/02/16(土) 12:19:54
>>540
今までの、その「不正確」への反論は全部スルーなのは何故?
542デフォルトの名無しさん:2008/02/16(土) 12:20:14
>>540
で、連絡したの?
別に、連絡することは絶対に許さんぞとか、俺はスーパーハカーだから
もし連絡したらお前を社会的に抹殺してやるぞとか、そーゆーこと言ってるわけじゃないんだから
さっさとすればいいのに。
543デフォルトの名無しさん:2008/02/16(土) 12:21:58
>>539
どっちでもない立場である「著者に連絡しとくといい」を、
「修正が必要だという強弁」に誤読して反論してた人が
「修正が不要だという意見」を持っていた、というお話。
544デフォルトの名無しさん:2008/02/16(土) 12:22:09
「ファイルスコープ」 という言葉にも文句を言って欲しい物だな。
545デフォルトの名無しさん:2008/02/16(土) 12:23:59
>>543
ああなんだ、「お話」の内容を語っていたのか。
やけに現実と異なると思った。
546デフォルトの名無しさん:2008/02/16(土) 12:27:15
>>541 >525 や >531 は読んでないのか?
547デフォルトの名無しさん:2008/02/16(土) 12:41:11
2 Lexical conventions

p1
The text of the program is kept in units called source files in this International Standard.
A source file together with all the headers and source files included via the preprocessing directive #include,
less any source lines skipped by any of the conditional inclusion preprocessing directives,
is called a translation unit.

翻訳単位はソースファイルであると規格に書かれている。
そして、「ソースファイル」 はまとまったプログラムのテキストであると定義されているだけで、
別に OS のファイルの定義と等しくある必要は無い。
548デフォルトの名無しさん:2008/02/16(土) 12:45:56
> 翻訳単位はソースファイルであると規格に書かれている。
不正確w
549デフォルトの名無しさん:2008/02/16(土) 12:56:16
この国際標準規格においては、
ある単位でまとまったプログラムのテキストのことを「ソースファイル」と呼ぶ。
#include 指令によりインクルードされる全てのヘッダとソースファイルと一緒になったソースファイルのことを「翻訳単位」と呼ぶ。
ただし、プリプロセッサ指令により除外される行は除外する。
550デフォルトの名無しさん:2008/02/16(土) 13:00:52
↓こんな感じかなぁ。

プログラムのテキストはこの国際規格で「ソースファイル」と呼ばれる単位に保持される。
ひとつのソースファイルと #include を通して取り込まれるヘッダやソースファイルを
すべて併せ、 #if などでスキップされる行を減じて、「翻訳単位」と呼ぶ。

JIS の訳はどうなってんだろ?
551550:2008/02/16(土) 13:01:18
うは。被った。
552デフォルトの名無しさん:2008/02/16(土) 13:14:29
言葉は悪くない。
悪いのは>>503を生み出したゆとり教育。
金毘羅様を疑う前にまず自分を疑え。
比較検討しろ。試行錯誤しろ。すぐ2ちゃんに泣きつくな。
553デフォルトの名無しさん:2008/02/16(土) 13:22:27
規格の話にまで行っちゃったなw有りだけど、入門サイトの話題だぜw

俺としては、
・c言語経験者前提
・ファイルスコープという言葉は一般に使われている
から、件の文脈でファイル==翻訳単位と分かる。
503、509はサイトの前提には満たなかっただけ。
つまりサイトの選択ミス。

・c++入門者用のサイト
から、厳密性より分かりやすさ優先することは妥当。

と考える。


大体、cユーザーがFILEと言いつつストリームだったりするのはザラ。
翻訳単位はコンパイラにとってストリーム。
554デフォルトの名無しさん:2008/02/16(土) 13:24:25
一体どう読めば翻訳単位=ソースファイルになるんだ・・
不思議だな
555デフォルトの名無しさん:2008/02/16(土) 13:26:49
翻訳単位=加工されたソースファイル
556553:2008/02/16(土) 13:28:19
補足。
俺は503が悪いとは思ってない。
学習には積み重ね、つまり順序が必要。
2chにレスして、足りない知識に指摘されたなら、その基礎を学べば良いだけ。

まぁ、試行錯誤が重要なのも間違い無いけどね。
557デフォルトの名無しさん:2008/02/16(土) 13:40:57
「ファイルスコープ」は C の規格で翻訳単位全体にわたるスコープとして使われてたけど、
C++ の規格では使われなくなってるみたい。やっぱり誤解する人がいたからなんだろうね。
558469:2008/02/16(土) 13:53:47
>>502
thx
比較関数にポインタの比較を含める手法があるんですね。参考になります。
いくつかのコンテナを同期させる手間がかかってしまうのは仕方ないですか。
559デフォルトの名無しさん:2008/02/16(土) 13:54:06
マイクロソフトのC++言語リファレンスくらいじゃ、話になりませんかね?

http://msdn.microsoft.com/library/ja/vclang/html/_pluslang_scope.asp
>File scope
560デフォルトの名無しさん:2008/02/16(土) 13:55:09
おはなしにならない
561デフォルトの名無しさん:2008/02/16(土) 14:09:10
了解です。

こちらはどうでしょうか?
http://www.boost.org/doc/html/variant/design.html
>file scope

これも間違った使い方ですよね?
562デフォルトの名無しさん:2008/02/16(土) 14:16:45
規格の話するのに規格以外のリファレンス持ってくるとかあり得ない
563デフォルトの名無しさん:2008/02/16(土) 14:30:28
ですよね〜w

マイクロソフトとBoostも、
ファイルスコープなんて単語使ってもらっちゃ困りますよねw
564デフォルトの名無しさん:2008/02/16(土) 14:47:28
CFactoryTemplate g_Templates[]= {
  L"Dump", &CLSID_Dump, CDump::CreateInstance, NULL, &sudDump
};
↑これってCFactoryTemplateクラスの配列(要素は1個)を作ってL"Dump",&CLSDI_Dump,...をコンストラクタに渡しているってこと?
ちなみにCFactoryTemplateはコンストラクタが定義されていないんですけど、こういうのアリなんでしたっけ?

class CFactoryTemplate {

public:

  const WCHAR *       m_Name;
  const CLSID *       m_ClsID;
  LPFNNewCOMObject      m_lpfnNew;
  LPFNInitRoutine      m_lpfnInit;
  const AMOVIESETUP_FILTER * m_pAMovieSetup_Filter;

  BOOL IsClassID(REFCLSID rclsid) const {
    return (IsEqualCLSID(*m_ClsID,rclsid));
  };

  CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) const {
    CheckPointer(phr,NULL);
    return m_lpfnNew(pUnk, phr);
  };
};



565デフォルトの名無しさん:2008/02/16(土) 14:49:51
>>559,561
検索乙。不正確な記事だから著者に連絡しとくといい。

・・・あ、 MSDN のやつは既出みたいね。
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=99170
566デフォルトの名無しさん:2008/02/16(土) 14:53:24
>>564
Cの構造体や配列の初期化と一緒。
そういう初期化ができる型を集成体と言う。
567デフォルトの名無しさん:2008/02/16(土) 14:54:48
>>566
そうなんだ。。いままで知らなかった。。
ありがと
568デフォルトの名無しさん:2008/02/16(土) 15:07:20
>>565
おお、GJ。
>>557が「やっぱり誤解する人がいたからなんだろうね」
って書いてたから、使わなくなった理由とかを探してた。
それ読んでやっと分かった。

誤解する人がいたから、ではなく、
namespaceが追加されたから、
名前空間スコープ、無名名前空間スコープ(グローバル名前空間)
という上位概念で置き換えたってわけか。
569デフォルトの名無しさん:2008/02/16(土) 15:14:15
>>568
無名名前空間スコープとグローバル名前空間スコープとは違うスコープだぞ、いちおう。
570デフォルトの名無しさん:2008/02/16(土) 15:23:19
>>569
そうだった。
素で間違えた・・・。
571デフォルトの名無しさん:2008/02/16(土) 15:33:45
規格厨消えた?
572デフォルトの名無しさん:2008/02/16(土) 17:49:58
この場合、どれが規格厨?
573デフォルトの名無しさん:2008/02/16(土) 21:41:48
汎整数拡張の勉強をしていて、intとunsigned intはどうなるのだろうと思い実行してみたところ、
intは予想通りの動作をしたんですがunsigned intがよく分からない動作をします。

unsigned int i = 0;
unsigned int j = 0xFFFFFFFF;
unsigned int k = 0xFFFFFFFE;
unsigned int l = 0xFFFFFFFF;
i += 0xFFFFFFFF;
printf("i=%d, j=%d, k=%d, l=%d\n", i, j, ++k, +l);

これが全部-1になってしまいます。
汎整数拡張とは違うと思うのですが、理由が分かりません。
どうしてこうなるのですか?
574デフォルトの名無しさん:2008/02/16(土) 21:56:03
>>573
"%d"してるからだろ常考。%uとかprintfの書式調べろ。
あと0xFFFFFFFFというバイトパターンは符号付整数型だと-1を表すからだろ。
575573:2008/02/16(土) 22:21:54
ありがとうございます!
%dは符号付表現だったのですね。勉強になりました。
576デフォルトの名無しさん:2008/02/18(月) 03:45:36
class の変数部分だけを
extern C
してstruct扱いにしてcから(c++でなくて)参照できますか?
577デフォルトの名無しさん:2008/02/18(月) 07:23:36
仮想関数テーブルがなければ大丈夫かもしれないが
どちらにしろカプセル化を壊すからやるべきでないことだけは確かだ。
アドレスだけ受け取って、
そのアドレスを渡して処理するヘルパ関数を使うとか。
578デフォルトの名無しさん:2008/02/18(月) 11:18:27
>>577
メンバ関数を呼ぶときにthisを積むことができない時点で無理。
579デフォルトの名無しさん:2008/02/18(月) 11:49:09
>>578
メンバ変数をアクセスしようってのに、メンバ関数を呼べないから
ダメというのは漏れにはちょっと途中のロジックがわからない・・・
580576:2008/02/18(月) 12:47:08
python.ctypesがstructにはアクセスできるけどclassが無理みたいなので
既存のc++コードのclassにpython.ctypesからアクセスするにはどうするか
知りたかったのです。結構難しいみたいですね。
class hoge
{
public:
char *data
int size
};
のdataとsizeにextern Cからアクセスしたかったのです
581デフォルトの名無しさん:2008/02/18(月) 12:49:11
>>300へのアンカーが欲しいのでレス書きます。
582デフォルトの名無しさん:2008/02/18(月) 15:01:18
C++初心者です。
C++ではクラスと構造体にはデフォルトのアクセス指定が違う以外に差異は無い、と入門書で読んだのですが、ということはC++では構造体は使わないで良いということでしょうか。
583デフォルトの名無しさん:2008/02/18(月) 15:07:24
そうでもない。

typedef struct cordinate{
  double x,y,z;
}CORDINATE;

こんなのは構造体で使う。
584デフォルトの名無しさん:2008/02/18(月) 15:21:13
public: と書くのも面倒だったらstruct使う。その程度。
585デフォルトの名無しさん:2008/02/18(月) 15:21:55
どちらも仮想関数テーブルを持った構造体になりうる
586デフォルトの名無しさん:2008/02/18(月) 16:59:21
>>576
C互換の構造体を基本クラスにすれば?
ATL/MFCのCRectとかはそうやってる。

struct C_Struct { };
class CPP_Class : public C_Struct { };
587デフォルトの名無しさん:2008/02/18(月) 18:07:00
>>586
それだと、cから参照できなくね?
588デフォルトの名無しさん:2008/02/18(月) 18:12:59
>>580
data, sizeというメンバがpublicになっている時点で、
hogeは実質ただの構造体なのでは?
コンストラクタやデストラクタを自分で特に定義していなくて、
メンバ関数もカプセル化じゃなくコードの再利用だけを目的にしているような。
だとすれば、メモリ上ではCの構造体と同じだから直接python.ctypesに渡せばOK。
ちなみに仮想関数を持っている場合はダメ。
>>586の方法なら一応動くけど設計を見直した方がいい。
589デフォルトの名無しさん:2008/02/18(月) 18:30:45
>>587
// C
struct C_Struct { };
void c_func(C_Struct*);

// C++
class CPP_Class : public C_Struct { };
CPP_Class hoge;
c_func(&hoge);

>>576がどういう使い方するのか知らんが、C互換の部分だけ見せる事はできるぞ。
590デフォルトの名無しさん:2008/02/18(月) 19:48:52
public 継承は怖いなあ。
そんなことしなくても不完全型使えばいいんじゃね。
591デフォルトの名無しさん:2008/02/19(火) 00:00:40
Modern C++ Designを読破した人でお分かりになる人
がいたら教えてください。

『第4章 小規模オブジェクトの割り当て』
のP88にチャンクのブロック数をunsigned charに収まる値に
制限した理由について、もしこれをunsigned shortにした
場合、sizeof(unsigned short)よりも小さなサイズのブロック
を割り当てることができなくなることが書かれていますが、
何故だか分かりません。ブロックサイズとブロック数は独立
に管理してるものなのでブロックサイズは1バイトだろうが何バイト
だろうが任意に指定できるはずです。

592デフォルトの名無しさん:2008/02/19(火) 00:17:55
その本は読んだことないけどエスパー回答してみる
フリーブロックの管理が連結リスト方式だとすると、あるブロックが解放されたとき、そこに次の空きブロックの位置を書き込まなければならない
総ブロック数がunsigned charの最大値以下なら、空きブロックの位置を保持するのに1バイトで足りるが、
総ブロック数がそれより多いなら、空きブロックの位置を保持するにはもっと領域が必要だ
解放されたブロックのサイズが1バイトでは、そこに次の空きブロックの位置を書き込むことはできない
593デフォルトの名無しさん:2008/02/19(火) 00:55:12
struct A
{
template<class T>
struct tmp{ T *pt; tmp( T *p ){ pt = p; } };
operator struct tmp(){ return tmp<struct A>( this ); };
A( tmp<struct A> &tmp ){ ... };
};

上の方でもでてたけど、こういうコードって何の意味があるの?
594デフォルトの名無しさん:2008/02/19(火) 01:06:43
>>592
すごいです。クリアになりました。

確かに未使用ブロックの先頭には次の利用
可能なブロックのインデックスを書き込みます。このインデックスのサイズが
もし2バイト(unsigned short型)なら、ブロックサイズを最低でも2バイト確
保しなければインデックス自体を書き込めないことになりますね。
595デフォルトの名無しさん:2008/02/19(火) 02:02:37
>593
>489 に
//非const参照で一時オブジェクトを受け取る対応。
って書いてあるやん。

俺の理解によると、その意味で A( tmp<struct A> "&" tmp) にしちゃ駄目ぽ。
通常の非 const 参照は一時オブジェクトを受け取れないので代わりに参照の働きをする tmp_ref を自前で導入してる。
tmp_ref<A> は A& を表していて、tmp_ref<A> への変換演算子が A → A& (ただし A が一時オブジェクトでも OK)の変換に相当してると思えば OK?
596デフォルトの名無しさん:2008/02/19(火) 02:22:49
場違いだったらすまん、
if文で、if (音を感知したら)
do ○○ っていうプログラムを考えているんだけど

その音を感知する部分で何か有効的な物ある?
597デフォルトの名無しさん:2008/02/19(火) 02:24:57
スレ違い

サウンドプログラミング4
http://pc11.2ch.net/test/read.cgi/tech/1185340076/
598デフォルトの名無しさん:2008/02/19(火) 02:56:06
struct foo{ struct foge{}; };
struct bar : foo{ struct foge{}; };

で、barの型からfogeと言う名のstructを導出する時、fooのものを選ぶかbarのものを選ぶかってどうやるんですか?
599デフォルトの名無しさん:2008/02/19(火) 03:19:05
お願いだからコンパイルの通るコードを書いてくれ
600デフォルトの名無しさん:2008/02/19(火) 03:19:38
通るけど?
601デフォルトの名無しさん:2008/02/19(火) 03:22:41
foge ← bar のやつ
foo::foge ← foo のやつ
602デフォルトの名無しさん:2008/02/19(火) 15:53:51
基底クラスに宣言した型を返すタイプの演算子オーバーロードって継承先では使用できないのでしょうか?

// ■ペースクラス
template <typename T>
class BASECLASS
{
protected:
unsigned long val;

public:
BASECLASS() {
val = 0;
};
~BASECLASS() {};

// 継承する型によって変化させたい
T& operator =(unsigned long val32) {
val = val32;
return *this;
}
operator unsigned long() {
return val;
}
};
603デフォルトの名無しさん:2008/02/19(火) 15:54:42
>>602 続き

// ■クラスA
class ChogeA : public BASECLASS<ChogeA>
{

};

// ■クラスB
class ChogeB : public BASECLASS<ChogeB>
{

};

// ■メイン
void main()
{
ChogeA hoge1;
ChogeB hoge2;
unsigned long tmp;

tmp = hoge1; // ○コレは動く

hoge1 = hoge2 = 10; // ×コンパイルエラーの位置

}

エラーメッセージ:'Choge::operator = (unsigned long)'に一致するものが見つからない

うまいこと引き継がれていないみたいで・・・
604デフォルトの名無しさん:2008/02/19(火) 16:59:31
代入演算子は継承されないとオモタ
605デフォルトの名無しさん:2008/02/19(火) 17:01:30
operator =は自動的に基底クラスのものを参照するようにならないメンバの一種。
規格では、派生クラスのデフォルトので上書きされるためと説明されていたはず。
派生クラスでいちいち定義すればいいのだけど、面倒と言われればそれまで。
class ChogeA : public BASECLASS<ChogeA>
{
public:
ChogeA& operator =(unsigned long val32)
{
return BASECLASS<ChogeA>::operator =(val32);
}
};
606デフォルトの名無しさん:2008/02/19(火) 17:17:33
派生クラスで
using BASECLASS<ChogeA>::operator =;
って宣言すればおk

あと
return *this;
の部分はダウンキャストが必要な気がする
607デフォルトの名無しさん:2008/02/19(火) 17:23:22
>>603
今の場合、コンパイラが暗黙に定義するコピー代入演算子が
派生クラスには存在している。基底クラスとはスコープが
異なるためオーバーロードにはならず、以下のものしか
候補にならないた一致するoperator=が無いと怒られる。
ChogeA& operator=(const ChogeA&);

ちなみに危険ではあるが

T& operator =(unsigned long val32) {
val = val32;
return *static_cast<T*>(this);
}
}
};

class ChogeA : public BASECLASS<ChogeA>
{
public:
using BASECLASS<ChogeA>::operator=;
};

// ■クラスB
class ChogeB : public BASECLASS<ChogeB>
{
public:
using BASECLASS<ChogeB>::operator=;
};

として可視にすればオーバーロードのセットに入るので
これでも動くかと。
608602:2008/02/19(火) 20:01:13
ありがとうございます。

>>604
>>605
ググりましたところC++入門でその旨記述ありました…お恥ずかしい。
ttp://www-glc.kek.jp/subg/offl/OOjlc/cppgrammer.html

>>606
>>607
凄い!
動作いたしました、感動です。
ちなみにダウンキャストは
return *((T*)(this))としました。

"危険"というのがおっかないですが、基底クラス側で派生クラスのメンバを呼び出したりしたら…ということでしょうか。
609デフォルトの名無しさん:2008/02/19(火) 20:12:44
>>602
継承される可能性のあるクラスはコピーコンストラクタやoperator=をprivateにするのが原則。
class Base {
public:
    Base &operator=(const Base &);
};

class Derived {
public:
    Derived &operator=(const Derived &);
};

void foo(Base *p, const Base *q)
{ *p = *q; }

void bar() {
    Base b;
    Derived d;
    foo(&d, &b); // 何が起こるだろう?
}
610デフォルトの名無しさん:2008/02/19(火) 21:13:58
>>609
privateにしてしまうと、派生クラスのオブジェクトの正しいコピーと代入
が行えない。(Effective C++ Item12)
せめてprotectedにすべきではないか。
611デフォルトの名無しさん:2008/02/19(火) 21:19:49
>>608
最後にキャストしてるから特に危険ではなかったか。
ただ、クラスのデザインとしては。。
やはり、>>605のように基底クラス部分の代入は
基底クラスの代入演算子に行わせて、派生クラス部分
は派生クラスの代入演算子に行わせるのが正等かつ
可読性が良いと個人的には思う。

>>610のメイヤーズのとおり。
612デフォルトの名無しさん:2008/02/19(火) 21:42:55
>>610
ポリモーフィズムを前提にするようなクラスに対して、
コピーはまだしも代入をまっとうに定義できるケースは珍しいだろ。
継承されないクラスでもコピーや代入は出来なくて当たり前。
コピーだけが意味を持つ場合はこうする。
class Base {
protected:
    Base(const Base &);
private:
    Base &operator=(const Base &);
public:
    virtual std::auto_ptr<Base> clone() const
    { return std::auto_ptr<Base>(new Base(*this)); }
};
613デフォルトの名無しさん:2008/02/19(火) 21:50:29
>>612
漏れは「継承される可能性のある」と、「ポリモーフィズムを前提にする」は
結構違うと思う。違わないようにするべきだという立場もわかるけど。
614デフォルトの名無しさん:2008/02/19(火) 22:04:30
>>612
継承される可能性のあるケースとは継承されないケース
もあるわけで、盲目的にコピー、代入を禁止するのは
柔軟性を損ねる。cloneによる深いコピーにしても
実行コストを考えると使いたくないケースは
特に組み込みではよくある。残念ながらnewは小さい
オブジェクト用のアロケータではない。
クラスの使用方法を明確に規定するのが前提だが
そうでないケースでは様々な拡張に応じられるように
しておくべきだと思う。
615デフォルトの名無しさん:2008/02/19(火) 23:26:05
>>613
std::unary_functionみたいのを除けば
デストラクタがvirtualかどうかではっきり決まると思うけど。
>>614
どういうクラスを想定してるの?
子クラスのインスタンスに親クラスのインスタンスを代入した場合の動作なんて、
いちいち決めても不毛なだけだと思うけどなあ、普通は。
元のインスタンスの決まった属性だけ読み出すという処理なら割と自然だと思うけど。
class Base {
public:
    explicit Base(const Base *);
    void assign_basic_attributes(const Base *);
};

class Derived {
public:
    explicit Derived(const Derived *);
    void assign_all_attributes(const Derived *);
};
616デフォルトの名無しさん:2008/02/19(火) 23:39:06
>継承される可能性のあるクラスはコピーコンストラクタやoperator=をprivate>にするのが原則。

流れからして、このレスが明後日のほうへ行ってしまってると感じた。

617デフォルトの名無しさん:2008/02/20(水) 00:02:46
だからsealedを導入しろって兄ちゃんがあれほど
618デフォルトの名無しさん:2008/02/20(水) 00:04:44
C++プログラマのオマエらからしてC#はどうなの?
619デフォルトの名無しさん:2008/02/20(水) 00:07:13
>>618
Javaじゃん。
つーか、仮想マシンが必要な言語と比較対照にはならんでしょ。
620デフォルトの名無しさん:2008/02/20(水) 00:08:40
むしろライバルはD
621デフォルトの名無しさん:2008/02/20(水) 00:11:06
.NETがLinuxに移植されたらC#もありかなと思って。
622デフォルトの名無しさん:2008/02/20(水) 00:11:46
つMONO
623デフォルトの名無しさん:2008/02/20(水) 00:12:22
Dいいね
624デフォルトの名無しさん:2008/02/20(水) 00:13:17
C#は大人しくJavaと闘ってなさい。C++とはどちらも無縁です。
Dもまた同じく。必要のある所ではC++もDもC#/Javaも必要なのは変わりないのです。
625デフォルトの名無しさん:2008/02/20(水) 00:16:59
Dが必要な場所が思いつきませんw
626デフォルトの名無しさん:2008/02/20(水) 00:17:50
もうOOPも手続き型も飽きたな。
関数型言語を使う仕事がしたい。
627デフォルトの名無しさん:2008/02/20(水) 00:18:52
OCamlとF#の出番だな。
628デフォルトの名無しさん:2008/02/20(水) 00:29:23
民間企業は面白くない。
研究室とかに篭ってシコシコ勉強がしたい。
629デフォルトの名無しさん:2008/02/20(水) 00:43:03
C#やったあとにJavaをやったら、C#が後発と言うだけあってC#が素晴らしく見えた。

>>618
LINQはSTL並に面白そうだと思っているんだけど、遊んでいる暇がない。
630デフォルトの名無しさん:2008/02/20(水) 01:15:24
俺の仕事で、関数型言語を覚えてまで使う理由が見当たらない。
こうぶんきなんて解析せんし、無限計算もやらん。遅延評価も
価値を持ちそうにない。なんではやってるんだ。

Dのがいい。
631デフォルトの名無しさん:2008/02/20(水) 01:33:55
>>630
コンパイラはLispとかで書かれてることもあるんじゃね?
632デフォルトの名無しさん:2008/02/20(水) 08:11:20
>>630
はやってるの?
633デフォルトの名無しさん:2008/02/20(水) 08:19:55
>>630
自分の知らない計算パラダイムを知ることによって世界が広がるぞ、マジで

あんたの言ってることは「2次方程式なんて実生活で使わないから
学校で勉強する意味がわからない」とかぬかすガキと似たようなもんだ

>>631
コンパイラはMLとかHaskellの方がやりやすいと思う
634デフォルトの名無しさん:2008/02/20(水) 08:29:31
>>618
Windowsでしか走らない時点で興味ない。
635デフォルトの名無しさん:2008/02/20(水) 08:35:56
>>633
LinuxはLispと聞いたことがある。
636デフォルトの名無しさん:2008/02/20(水) 09:00:33
>>634
> Windowsでしか走らない時点で興味ない。

つMONO
637デフォルトの名無しさん:2008/02/20(水) 10:26:19
>>633
実際の話、理数系が苦手だった奴って
日常会話でもアホすぎてむかつくことが多いもんなw
638デフォルトの名無しさん:2008/02/20(水) 11:08:22
◯理数系が苦手だったと得意気に言う香具師
639デフォルトの名無しさん:2008/02/20(水) 12:02:08
俺はそんな奴をプギャーしておこう。
640デフォルトの名無しさん:2008/02/20(水) 12:58:23
○理数系が得意だったとは決して言わない香具師
641デフォルトの名無しさん:2008/02/20(水) 14:49:52
>>618
昔なら「こういうのはVBで書けば5分でできるんだろうな。VBなんか使い方しらんけどpu」と
思ってたような種類のアプリをサラッと書くのに使ってる。UI 作るのが楽なので重宝してる。
642デフォルトの名無しさん:2008/02/20(水) 15:37:55
おまえらの開発プラットフォームは何?

1.Windows
2.Unix系(Linux含む)
3.組み込み
4.その他

ほとんどが1,2だろうな
643デフォルトの名無しさん:2008/02/20(水) 15:40:44
Unix系にはMacを含みますか?
644デフォルトの名無しさん:2008/02/20(水) 15:48:10
おう、こうするよ。

1.Windows
2.Unix系(Linux含む)
3.組み込み
4.Mac
5.その他

ほとんどが1,2だろうな
645デフォルトの名無しさん:2008/02/20(水) 16:09:01
組込みがターゲットの開発は、ふつうクロスだろ上皇
646デフォルトの名無しさん:2008/02/20(水) 17:28:20
まあそうだけど、例えばルネサスのコンパイラとか
68kのコンパイラとかっていう程度でいいじゃん。
どっちもWindowsのツールになるが。

あまり興味ないから、質問取り消すわ。
647デフォルトの名無しさん:2008/02/20(水) 23:16:42
2と3なら3が多いと思うのだが・・・どうでもないのか?
648デフォルトの名無しさん:2008/02/21(木) 00:47:25
>>647
あ そんなもん?
649デフォルトの名無しさん:2008/02/21(木) 01:37:01
質問が二つほど。

関数宣言と関数中身は一対一とおもってたんですけど、
すでにライブラリに入っている関数中身をプロジェクト内に書くということは
問題ないのでしょうか?

sprintfで書き込むのに必要な配列のサイズを知る方法ってあるのでしょうか?
650デフォルトの名無しさん:2008/02/21(木) 02:30:15
C++でsprintfで書き込むのに必要なバッファの大きさを知る一般的な方法はないね。
C99だと書込先にヌルを指定すれば、戻り値でわかるようになったんだけど。

VC++の_scprintfのように独自関数を使ったり、
ヌルデバイスをfopenしてfprintfしたりという環境依存の方法か、
標準ライブラリのものを使うのを諦める。
(自分でバッファサイズが分かるものを作ったり、あるいはBoost.Formatのような既製品を使ったり)
651デフォルトの名無しさん:2008/02/21(木) 21:32:15
>>649
普通はダメ。
ただし、主に移植性を重視するUNIXのプログラムで、
システムが提供するライブラリ関数と同名の関数を自分で再定義する場合はある。
例えばbasename(3)は標準化される前から多くのUNIXで提供されていて、
しかも挙動が微妙に違っていた。そこで、basenameが無かったり、
あっても標準と違っているOSではbasenameを自前で定義することがある。
そういうコードをリンクできるか、再定義した関数をリンクしたライブラリから
隠すことができるかどうかはリンカ次第。
652デフォルトの名無しさん:2008/02/21(木) 22:38:37
右辺値参照が導入されたら、これまでの左辺値参照の存在意義はどうなりますか?

struct X {};
X f();

X&& = f() //OK Xは右辺値参照

X obj;
X&& = obj; //OK Xは左辺値参照

&&があれば、両方で使えますよね。
653デフォルトの名無しさん:2008/02/21(木) 22:39:24
間違えた。

右辺値参照が導入されたら、これまでの左辺値参照の存在意義はどうなりますか?

struct X {};
X f();

X&& x = f() //OK xは右辺値参照

X obj;
X&& x = obj; //OK xは左辺値参照

&&があれば、両方で使えますよね。
654デフォルトの名無しさん:2008/02/21(木) 22:45:49
両方で使えるのか?
区別できるからこそ(ry
655デフォルトの名無しさん:2008/02/21(木) 22:52:32
RVOをさせたくない場合、どう書けばいいですか?
gccが頭よすぎで、全部RVOされます
656デフォルトの名無しさん:2008/02/21(木) 23:08:09
代入演算子が呼ばれたのでいいなら
初期化じゃなく代入にすればいいが、
どうしてもコピーコンストラクタが呼ばれて欲しいとなると、
一旦一時変数を作ってそれで受けて、
さらにそれをコピーするしかないのかな。

ただ、RVO に依存して挙動の変わるコードは感心しないので
何らかのチェックのために行うのでなければ、そういうことはしない方がいい。
657デフォルトの名無しさん:2008/02/21(木) 23:59:44
>>649
ostringstream foo;
foo << "hoge hoge pu-";
foo.str().c_str(); <- 文字列へのポインタ
658デフォルトの名無しさん:2008/02/22(金) 00:25:35
>>649>>651
<new>のoperator new, new[], delete, delete[]は自分で定義してもよい。
ユーザが定義しなければライブラリの実装が使われるって規定がある。
659デフォルトの名無しさん:2008/02/22(金) 01:01:31
>>655
呼ぶ側と呼ばれる側の翻訳単位分けてみたらどう?
660デフォルトの名無しさん:2008/02/22(金) 01:03:50
RVO は翻訳単位関係ないぜよ。
661デフォルトの名無しさん:2008/02/22(金) 01:25:42
処理系依存なんだし、関係無いかどうかはgccの実装次第じゃね?

翻訳単位分ければインライン化は阻害される思うし(多分)、
そしたらRVOも阻害される可能性はあるかと。
リンカが頑張ってたら駄目だろうけどね。
662デフォルトの名無しさん:2008/02/22(金) 01:30:15
>>656
move semanticsしたのと、してないのを比べたいんじゃね?
コストが掛かるはずの普通の代入でも、RVO効くとコピーコスト0になるから。
663デフォルトの名無しさん:2008/02/22(金) 01:44:35
>>653
多重定義したときに区別を付けるために必要。
664デフォルトの名無しさん:2008/02/22(金) 01:49:25
>>653
左辺値参照と右辺値参照の区別があって一番うれしい場面は,
関数の実引数が右辺値なのか左辺値なのかを関数の定義内で
識別できるところです.例示しているコードにおいては,
右辺値参照が一時オブジェクトを束縛できることを除いて
x を右辺値参照型にで宣言しようが左辺値参照型で宣言しようが
本質的な違いが現れることは無いように思います.

>>655
試していないのでアレですけれど
struct X{ X(int i) : p_(new int(i)) {} ~X(){ delete p_; } int* p_ };
X f(bool b){
if (b) { return X(42); }
return X(43);
}
あたりだとRVOが阻害されませんか?
665デフォルトの名無しさん:2008/02/22(金) 01:56:46
>>655
最適化オフでもRVOするの?
666デフォルトの名無しさん:2008/02/22(金) 07:34:56
-O0 でも RVO するね。
667デフォルトの名無しさん:2008/02/22(金) 14:46:39
そこそこ大規模なプロジェクトで,使われる例外についての
統制を取りたいと思ったとき便利な方法はないだろうか.
どこかの馬鹿が int を throw するなどというバカげたことを
していないということをコンパイル時に保証するのは無理?

プロジェクト全体として std::runtime_error と
std::logic_error から派生させたいくつかのクラスを
投げることを規約としているのだけど,馬鹿が適当な
ものを投げてくるかもしれない.

結局 throw を全部見て回るしかない?
668デフォルトの名無しさん:2008/02/22(金) 14:50:28
例外禁止がベスト、オプションで切っとけ
669デフォルトの名無しさん:2008/02/22(金) 15:04:03
>>668
ちょ・・・それわ,無理w
マージ担当者にされてあたふたしてる.
670649:2008/02/22(金) 15:15:10
>>650
>>651
ありがとう。勉強になりました。
そうか・・リンカ依存なのか〜
671デフォルトの名無しさん:2008/02/22(金) 16:09:08
>>667
っ 例外指定
672671:2008/02/22(金) 16:10:16
って、コンパイル時のチェックにはならないんだっけかそういえば・・・
673デフォルトの名無しさん:2008/02/22(金) 16:46:20
>>662
まさに言う通りのことを試したいんです。
-O0でもRVOします。
674デフォルトの名無しさん:2008/02/22(金) 17:12:19
volatile int norvo(){ ... }
675デフォルトの名無しさん:2008/02/22(金) 18:16:10
>>662
代入では RVO はきかんぜよ
676デフォルトの名無しさん:2008/02/22(金) 18:20:07
つ -fno-elide-constructors
677デフォルトの名無しさん:2008/02/22(金) 18:34:48
>>671
無理
例外指定しても投げようと思えば何でも投げられる。
unexpected exceptionにはなるが。
678デフォルトの名無しさん:2008/02/22(金) 19:56:28
C++の例外は破綻しているから使っちゃ駄目だって
679デフォルトの名無しさん:2008/02/22(金) 20:03:27
破綻してないヨ。
680デフォルトの名無しさん:2008/02/22(金) 20:07:24
破綻してないアル!
681デフォルトの名無しさん:2008/02/22(金) 20:48:10
C++0x では例外周りでの新機能ってあるんですかね.
っていっても自分でも新機能を思いつかないんだけど.
682デフォルトの名無しさん:2008/02/22(金) 22:07:39
move semantics ほしいな
683デフォルトの名無しさん:2008/02/22(金) 23:09:15
>>681
例外用の関数がいくつか追加されてたはず。
例えば catch(...) でも例外が取得できるようになった、とか。
684デフォルトの名無しさん:2008/02/23(土) 04:31:41
>>667
そんなもんヌルポインタにアクセスしたり整数オーバーフローさせたり
無茶なキャストでコンパイラ黙らせたりしてるのと同じで、馬鹿が混ざっている
という前提ではどうしようもないもんだろ。

なんで例外だけ取り立ててどうにかしようと思うの?
685デフォルトの名無しさん:2008/02/23(土) 04:34:57
main()でcatch (...)して、全開発者に同報メールを送るようにでもしておけばいいじゃんw
686デフォルトの名無しさん:2008/02/23(土) 04:36:35
>>684
マージ担当の引き継ぎ事項に書いてあったから.
687デフォルトの名無しさん:2008/02/23(土) 04:36:36
例外クラスに命名規則をつけておけば、
それに従っていない例外を投げている throw 式を
正規表現検索できると思う。
688デフォルトの名無しさん:2008/02/23(土) 04:41:54
>>685
int main() {
 try {
  // main の中身
 } catch(const std::runtime_error& e) {
  // ここは規約通り
 } catch(const std::logic_error& e) {
  // ここは規約通り
 } catch(...) {
  // ここに飛んできたらおかしい
 }
}

実際に飛んでこないと分からないがな。
689デフォルトの名無しさん:2008/02/23(土) 04:46:48
>>686
そういうことなら throw と catch を検索して様子を見るぐらいで十分でしょ。
それ以上は他の未定義動作や禁じ手と同じで、完全なチェックは無理だと思うよ。
690デフォルトの名無しさん:2008/02/23(土) 05:12:46
pimpl イディオムを使うとき、ポインタはどれがいいんでしょう?
const std::auto_ptr<Impl> かな、と思うのですが、
boost::scoped_ptr<Impl> でもよさそうだし、
あんまり意味ないかもしれないけど boost::shared_ptr<Impl> でも。
691デフォルトの名無しさん:2008/02/23(土) 05:20:45
>>690
普通は boost::scoped_ptr 。
std::auto_ptr は少し安全性が落ちる。
boost::shared_ptr は冗長。
692デフォルトの名無しさん:2008/02/23(土) 05:24:36
>>686
throw を次のようにマクロで置き換える。

#ifndef NDEBUG
#define throw DEBUG_CHECK_EXCEPTION_(),
struct DEBUG_CHECK_EXCEPTION_ { };

template <typename T>
void operator,(DEBUG_CHECK_EXCEPTION_, const T& e) {
BOOST_STATIC_ASSERT((
::boost::is_same<T, ::std::runtime_error>::value ||
::boost::is_same<T, ::std::logic_error>::value ||
::boost::is_base_and_derived<T, ::std::runtime_error>::value ||
::boost::is_base_and_derived<T, ::std::logic_error>::value));
std::cout << typeid(T).name() << std::endl;
throw e;
}
#endif

これで静的にチェックできるはず。
693デフォルトの名無しさん:2008/02/23(土) 05:28:37
ミスった。引数が逆だ。

#ifndef NDEBUG
#define throw DEBUG_CHECK_EXCEPTION_(),
struct DEBUG_CHECK_EXCEPTION_ { };

template <typename T>
void operator,(DEBUG_CHECK_EXCEPTION_, const T& e) {
BOOST_STATIC_ASSERT((
::boost::is_same<T, ::std::runtime_error>::value ||
::boost::is_same<T, ::std::logic_error>::value ||
::boost::is_base_and_derived<::std::runtime_error, T>::value ||
::boost::is_base_and_derived<::std::logic_error, T>::value));
std::cout << typeid(T).name() << std::endl;
throw e;
}
#endif
694デフォルトの名無しさん:2008/02/23(土) 05:35:14
あ、テストコードまぎれてる。
typeid のところは無視して。
695デフォルトの名無しさん:2008/02/23(土) 05:44:08
>>693
<: が [ の代替表現に引っかかる。 < ::std... とスペース一個空けとかないといけない。

throw する型によってエラーが出るのは確認できた。役に立ちそうな予感はする。
ただ、 ~T() throw () {} みたいなのがコンパイルできないのがマズイ感じ。
標準ライブラリの中に throw () とか付いてる可能性を考えると、致命的かも。
696デフォルトの名無しさん:2008/02/23(土) 08:08:44
http://pastebin.windy.cx/?page=view&id=1203718571
これみたいに基底クラスを派生クラスのメンバとして
参照しちゃうのってあり?ポリモーフィズムとしても、
メンバとしても、基底クラスにアクセスしたいとき。
697デフォルトの名無しさん:2008/02/23(土) 10:10:38
>>690
COW実装したいときはshared_ptrが便利
698デフォルトの名無しさん:2008/02/23(土) 11:07:20
D言語を使う場合、いいGUIツールがありますか?
それがない限り、使う気になりません。

それとどんな言語でも最初は仕様がキレイなんですよね。
あのC++だって当初はキレイだったんですよ。

ところが実用的に使われ始めて呪文のような
コードになってしまった。

C#もだんだん仕様が汚くなりつつあると聞いてます。

仕様がすっきりしてる言語なんて全く信用してません。
699デフォルトの名無しさん:2008/02/23(土) 11:17:42
>>698
で、C++についてのどういった相談事でしょう?
D言語のことはD言語スレへ、C#のことはC#スレへお願いします
700デフォルトの名無しさん:2008/02/23(土) 12:22:32
>>695
例外指定か・・・。なるほど。
throw じゃなくて THROW か何かを使わせることができるならそれが楽なんだが、
その規約を守らない人が出てくると・・・だしなあ。
Java みたいに throws ならいいのに・・・。
701デフォルトの名無しさん:2008/02/23(土) 14:15:12
>>699

>>623 - >>630

あたりを読んで言ってみただけです。
702デフォルトの名無しさん:2008/02/23(土) 14:18:17
D の IDE なら Descent だろうかね。
703デフォルトの名無しさん:2008/02/23(土) 14:25:32
>696
ふつーは、derived_class.BaseClass::Greeting()とかって書けばいいから
ポインタ一個分のオーバーヘッドが無駄と言えば無駄だけど、
まー別にいいんじゃねーの。
704デフォルトの名無しさん:2008/02/23(土) 14:28:24
>>696
あり得ない解決方法。
別メンバ関数(非仮想)を用意して、
そこで基底クラスの関数へ委譲すべき。
705デフォルトの名無しさん:2008/02/23(土) 14:30:18
Greeting は仮想関数にした上で、ね。

あるいは、Derived の Greeting を別関数にするか。
706デフォルトの名無しさん:2008/02/23(土) 18:18:59
SYSTEMCの勉強をしている、IC設計者です。
C++は初心者です。
C++で、class Signal を定義し、その中に、
string signal_name があったとき、
classを使う側で、
Signal sig1(); とだけすると、
そのsig1がsinanl_nameに自然に入るなんてことは
できないのでしょうか。
コンストラクタの工夫などで。

やはり、Signal sig1("sig1"); として
コンストラクタの中で渡されたstringで
signal_nameを初期化する処理を書いて、
をしなければなりませんか。

同じ sig1 をいう名前を
Signal sig1("sig1");
のように2回書くのがどうもなーと
思ったものですから。

707デフォルトの名無しさん:2008/02/23(土) 18:29:39
>>706
コンストラクタの工夫では無理だろう
工夫する余地があるとすればプリプロセッサマクロだが・・・
#define sig1() sig1("sig1")
・・・は無理矢理すぎるか

#define DECLARE_SIGNAL(name) Signal name(#name)

DECLARE_SIGNAL(sig1); → Signal sig1("sig1")
に展開させるくらいじゃないかな
708706:2008/02/23(土) 18:34:24
>>707
なるほど、マクロかあ。
そういう方向で考えて見ます。
どうもありがとうございました。
709デフォルトの名無しさん:2008/02/23(土) 18:41:19
fatal error C1060: ヒープの領域を使い果たしました。

テンプレートプログラミングの末路を見た。
710デフォルトの名無しさん:2008/02/23(土) 19:08:18
プリプロセッサでごにょごにょすりゃ出来るけど、
何か変なことをやろうとしているような気がする。
711デフォルトの名無しさん:2008/02/23(土) 20:28:04
>>709
コンパイラオプションでヒープをもっと増やせばいいだけ。
712デフォルトの名無しさん:2008/02/23(土) 20:33:15
コンパイルに使うヒープを増やせるのか?
713デフォルトの名無しさん:2008/02/23(土) 20:36:47
Visual C++だろ。
http://msdn2.microsoft.com/ja-jp/library/yz7kx3y2.aspx
/Zmコンパイラオプション
714デフォルトの名無しさん:2008/02/23(土) 21:19:01
テンプレート関連のコンパイルで内部的にループにでもなったとか。
Zmで解決すれば良いけど
715709:2008/02/23(土) 21:47:56
Zm2000にしても無理だったんだ。
716709:2008/02/23(土) 21:54:15
どうやら無茶なことをしようとしていたようだ。
あきらめるわw
717デフォルトの名無しさん:2008/02/23(土) 22:11:37
ちょっと質問です。VS2005、XP です。

大きさの等しい、文字列の配列と整数の配列がそれぞれあるとします。
文字列の配列を、整数の配列の値の順にソートしたいと思います。
std::sort など既存のソートアルゴリズムを使って、これを行ううまい方法はないでしょうか?

例:
std::string a[] = {"aaa", "bbb", "ccc", "ddd"}
int b[] = {7, 1, 5, 4}
の場合、a を "bbb", "ddd", "ccc", "aaa" の順に並び替えたいと言うことです。

実際は文字列だけでなくいろいろな型を使うので、
文字列と整数をメンバとして持つ構造体を作って operator < を定義して std::sort にかける・・・というのは、少し長すぎて気が引けます。
よろしくお願いします。
718デフォルトの名無しさん:2008/02/23(土) 22:42:09
>>717
構造体なんかつくらずにpairにしてvectorにでもいれて
比較関数を書いてsortさせるとか。
あるいは、いったんmapに突っ込んで取り出す。
719デフォルトの名無しさん:2008/02/23(土) 22:59:49
ああー、pair を使うってのは思いつきませんでした。
pair なら比較関数をかかなくとも、first の方にキーを入れれば、std::sort でソートできますね。ありがとうございました。
720デフォルトの名無しさん:2008/02/24(日) 00:09:06
>>690
auto_ptr は不完全型に使っちゃいけないことになってるから、候補からは外れると思うよ。
721デフォルトの名無しさん:2008/02/24(日) 00:41:30
>>720
間違った使い方しなければ大丈夫らしいよ
http://ml.tietew.jp/cppll/cppll_novice/article/221

まぁ、scoped_ptrでいいとは思うけど
722デフォルトの名無しさん:2008/02/24(日) 00:48:03
>>667
もしcppに細工することが出来るなら、
template <class T> inline void do_throw(const T &ex)
{ BOOST_STATIC_ASSERT((...)); throw ex; }
#ifdef NDEBUG
#define THROWS(spec)
#else
#define THROWS(spec) mycpp_throws spec
#endif
#define THROW(ex) do_throw(ex)
と定義しておいて、偽cppは本物のcppを実行してから#lineを見て
自分のプロジェクト内のコードにdo_throw以外のthrowがあったらエラーにする。
最後にmycpp_throwsをthrowに置換してコンパイラに渡せば一丁あがり。
一度これをやっておけば、コストを気にせず例外仕様をがんがん付けて
実行時の問題をデバッグすることも出来る。
723デフォルトの名無しさん:2008/02/24(日) 01:14:53
>>721
たいていの実装ではそうなんだけど、規格はテンプレート引数に不完全型を使った時点で
その効果は未定義としている。
724723:2008/02/24(日) 01:15:41
あ、記載があるのは 17.4.3.6 ね。
725デフォルトの名無しさん:2008/02/24(日) 08:40:54
BCC で変になってたとかいう話があったのはそれが原因か。
726デフォルトの名無しさん:2008/02/24(日) 08:46:27
最新のドラフトだと個別に許可されていればおkのようだな。
多分 shared_ptr 絡みで追加されたんだと思うが。
実際、許可されてるクラスは
shared_ptr, weak_ptr, enable_shared_from_this の3つだけだ。
727デフォルトの名無しさん:2008/02/24(日) 08:58:39
横から補足すると、これはあくまでも標準ライブラリ側の制限なので、
scoped_ptrや自前auto_ptrなら問題ない。
ただし不完全型をdeleteしたらundefined behaviourなので
(どう考えてもill-formedの間違いだと思うけど)、
自前auto_ptrを作るとしたらboost::checked_deleteを使うべし。
728デフォルトの名無しさん:2008/02/24(日) 09:45:19
checked_delete なんてのがあるのか.
しかしその実装を見てもなにやってるのかわからん.
まんなかの (void) sizeof(....ってなにやってんの?

template<class T> inline void checked_delete(T * x)
{
// intentionally complex - simplification causes regressions
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete x;
}
729デフォルトの名無しさん:2008/02/24(日) 09:50:06
実際に何らかの形で使わないとエラーにならない処理系でもあるんじゃない?
730デフォルトの名無しさん:2008/02/24(日) 10:02:04
>>729
使わないと最適化ですっ飛ばされちゃうこともあるのかねぇ.
731デフォルトの名無しさん:2008/02/24(日) 11:06:20
732デフォルトの名無しさん:2008/02/24(日) 11:56:33
>>728
sizeof(T)? 1: -1

sizeof(T) が 0 になることなんてあるの?
733デフォルトの名無しさん:2008/02/24(日) 12:00:07
不完全型
734デフォルトの名無しさん:2008/02/24(日) 13:18:23
struct Hoge {};

printf("%d", sizeof(Hoge));

→1

エーッ
735デフォルトの名無しさん:2008/02/24(日) 13:24:05
サイズ0だと色々困る
例えば
Hoge hoge[2];
&hoge[1] - &hoge[0] == 0
とかじゃまずい
736デフォルトの名無しさん:2008/02/24(日) 13:25:01
>>733
不完全型とはvoidとか
class Widget;
のこと?
だったらsizeof(void) sizeof(Widget)はコンパイルエラーになるんだけど。
737デフォルトの名無しさん:2008/02/24(日) 13:29:51
>>733
不完全型にはsizeof演算子は適用してはいけないと書かれてるんだが。
738デフォルトの名無しさん:2008/02/24(日) 13:33:53
>>736
コンパイルエラーになってほしいんだからそれでおk
739デフォルトの名無しさん:2008/02/24(日) 14:02:32
仮に 0 になる処理系があっても大丈夫という寸法なんだろう。
740デフォルトの名無しさん:2008/02/24(日) 14:08:00
>>736-737
それを利用してコンパイルエラーにさせるから、"checked_" だろ
741デフォルトの名無しさん:2008/02/24(日) 14:08:59
boostが使ってるね
742デフォルトの名無しさん:2008/02/24(日) 14:09:26
その boost の話なんだが・・・
743デフォルトの名無しさん:2008/02/24(日) 14:21:10
>>726
最小のフットプリントで不完全型を渡せる scoped_ptr の代替はないんだな。

unique_ptr でも不完全型を許可してほしいなぁ。 checked_delete 相当の
default_delete とか使うんだから、問題になることはないはず。
744デフォルトの名無しさん:2008/02/24(日) 14:39:41
default_delete は不完全型の時には診断が要求される
(A diagnostic is required if T is an incomplete type.) って書いてあるな。

デリータがテンプレートパラメータになってるから
デリータを自分で指定すれば好きに出来そうではある。
745デフォルトの名無しさん:2008/02/24(日) 14:45:33
>>744
そこまで書いておきながら、 unique_ptr に不完全型を許可する記述が無いのは
おかしいな。もしかして、書き漏らしてるだけ?
746デフォルトの名無しさん:2008/02/24(日) 14:46:54
>>738
>>740
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
仮に、sizeof(T)が0に評価されたときに
配列が-1という要素を持つことが許されないという理由でコンパイルエラー
にするという意図ならわかるが、>>733が言ってるとおりだとすると単に
不完全型だということなら、そもそもsizeof(T)自体がエラーの原因になるだろ。
だが、規格ではsizeof(不完全型)は許されていない。
規格に従えば、不完全型Tに対してsizeof(T)が0になることはない。

>>739
それなら納得
747デフォルトの名無しさん:2008/02/24(日) 15:00:26
よく考えてるなぁ
748デフォルトの名無しさん:2008/02/24(日) 15:05:54
全てのコンパイラが規格に従ってたら
BOOST_WORKAROUND なんてもんは必要ないな。
749デフォルトの名無しさん:2008/02/24(日) 15:09:35
>>745
デリータ次第だから default_delete に記述があれば十分だろう。
というか、これは不完全型は許可してないという記述じゃないのか?
いや、まあ挙動が定義されているからある意味許可はされているのか。
750デフォルトの名無しさん:2008/02/24(日) 15:32:45
>>749
default_delete については不完全型を許可している(コンパイルエラーになると
規定している)ように読めるけど、それは unique_ptr に不完全型を渡した場合の
動作について何か言っていることにはならないでしょ。 default_delete 以外も
使えるんだし。
751デフォルトの名無しさん:2008/02/24(日) 15:37:22
デリータはユーザが作った物も指定できるんだから、
規定できるわけないとまではいわんが
規定が無いのならユーザが自由にできるってことでしょう。
752デフォルトの名無しさん:2008/02/24(日) 15:58:15
>>751
個別の規定が無い場合は >>723-724 のとおり未定義ってことになってしまう。
753デフォルトの名無しさん:2008/02/24(日) 16:25:59
>>746
733は不完全型の場合にsizeof(T)が0になることがあるって意味だろ?
同じこと言ってると思うぞ
754デフォルトの名無しさん:2008/02/24(日) 16:43:49
規格では不完全型で sizeof (T) するとエラーにならないといけないが、
エラーにならず 0 になる処理系があって、その対策なんだろうという話だな。
755デフォルトの名無しさん:2008/02/24(日) 16:43:49
>>753
どのコンパイラ?
756デフォルトの名無しさん:2008/02/24(日) 16:45:10
>>752
ああ、あああ、ああ、そうか。
じゃあ未定義なんだろうな。
757デフォルトの名無しさん:2008/02/24(日) 16:45:31
>>753
それなら>>739の言い方が正しい。

>>733だと、まるで不完全型Tに対しては常にsizeof(T)が0になると誤解される。
758デフォルトの名無しさん:2008/02/24(日) 16:55:40
759デフォルトの名無しさん:2008/02/24(日) 17:18:01
>>755
俺に言われても知らない。733に聞いてくれ

>>757
誤解を招くってのは分かる
けど>>732に対して>>733なら「なることがある」だろ
# というか733みたいなおそらく一例を挙げただけの即答にツッコミ杉w

このスレに居るなら「すべきである」「しなければならない」みたいな違いに敏感だろうに・・・
760デフォルトの名無しさん:2008/02/24(日) 20:26:13
肩凝ってしょうがねえ
761デフォルトの名無しさん:2008/02/24(日) 20:58:03
&&の右辺値参照ってのは、右辺値を渡したときに渡した元のオブジェクト
はどうなってもいいという前提なの?これがmove semanticsというもの?



@
void f(X&& r);
f(X()); // move semantics X()の状態は保障されない。
// r は右辺値参照。

A
void f(X&& r);
X x;
f(x); //この場合(X&& r = x)は、rは左辺値参照。

B
void f(X& r);
X x;
f(x);

AとBは等価という理解でいい?
762デフォルトの名無しさん:2008/02/24(日) 21:05:45
>>761
元のオブジェクトがどうなってもいいっていうのが非 const 右辺値参照でしょ。

2がコンパイルできるようだと右辺値参照の意味がないような気がする。
コンパイルエラーになるんじゃね?
763デフォルトの名無しさん:2008/02/24(日) 21:14:41
template<int Value> struct base{};

struct a : base<0>{};
struct b : base<1>{};
struct c : base<2>{};
struct d : base<3>{};
......

何らかの型がbase<*>を継承している場合、その何らかの型とbaseの情報だけで
baseに指定されたテンプレートパラメータを取得する方法はありませんか?
764デフォルトの名無しさん:2008/02/24(日) 21:18:36
baseにpublic:enum{ VALUE=Value}とでもつけときゃいいじゃん
765デフォルトの名無しさん:2008/02/24(日) 21:18:51
どういう状況で取得したいのかわからないから、
これが使えるかどうか自信がないけど。
template<int n>
void f(base<n> const&)
{
}
766デフォルトの名無しさん:2008/02/24(日) 21:40:14
>>763
intならenum
typeならtypedef
で保存
767デフォルトの名無しさん:2008/02/24(日) 22:02:46
>>762
draftに以下の記述があるんだけど、これはどういう意味?

struct A {};

A a;
A&& ar = a;

The expression ar is an lvalue of Type A.
768デフォルトの名無しさん:2008/02/24(日) 22:03:25
派生クラスもテンプレ化するとか
769デフォルトの名無しさん:2008/02/24(日) 22:13:54
>>767
「 ar という式は型 A の左辺値である。」
・・・読んだまんまなんだが、こんな答えでいいのか?
770デフォルトの名無しさん:2008/02/24(日) 22:26:02
>>767>>762の「2はコンパイルエラーになるかも」を受けての質問だろ?
draftにそうあるなら左辺値になるんだろうな。

それを>>761の(2)と(3)でオーバーロードされたfに渡したら
左辺値扱いなので(3)の方が選ばれる・・・とか? 俺も仕様知らないけど
771デフォルトの名無しさん:2008/02/24(日) 22:34:57
>>770
説明不足だった。
ABのそれぞれの関数f()は、オーバーロードというつもりで
書いたわけじゃなくて渡す引数が左辺値なら、f()をどっちで定義しても
同義じゃないかと思った。

A
void f(X&& r);
X x;
f(x); //この場合(X&& r = x)は、rは左辺値参照。

B
void f(X& r);
X x;
f(x);
772デフォルトの名無しさん:2008/02/24(日) 22:49:50
>>771
2が通るんなら右辺値参照受け取る関数なんて恐ろしくて作れない。
773デフォルトの名無しさん:2008/02/24(日) 22:55:53
>>772
Aはとおるだろ。で、左辺値参照になるだけじゃねーの?
774770:2008/02/24(日) 22:59:32
>>771
説明不足なのはむしろ俺かwすまん
オーバーロードの意味じゃないのは分かってる
で、よく仕様知らないと言いつつ770で想定したのは↓
 A a;
 A&& ar = a;
 f(ar); //arは左辺値扱い(?)なのでオーバーロードがあったら f(A&); の方が優先的に呼ばれるかも
で、arについての話だけ。

で、本題だけど、f(A());のケースだとf(A&&)しか呼べないだろうけど
引数が左辺値ならf()はどっちでも同義だと思う。
775770:2008/02/24(日) 23:00:39
「で、」が多いのは気にしないで下さい><
776デフォルトの名無しさん:2008/02/24(日) 23:05:58
>>774
同じ認識になりますた。

で、オーバーロードの場合だと、左辺値引数を渡したら
左辺値参照を好むから void f(X&); が呼ばれるはず。
777770:2008/02/24(日) 23:06:56
>>772
もしコンパイルエラーにならなくても、
左辺値がオーバーロードでf(A&);に行くなら心配無いよな?
両方書いて、少なくともf(A&&)の方は「壊して良い」ってことになるから
778772:2008/02/24(日) 23:32:57
あー。
右辺値参照引数に左辺値が渡せないと、 unique_ptr みたいに移動だけを行うような
モノが作れないな。

しかし「左辺値参照になる」ってのは解せないな。受け取った側では実引数が
左辺値か右辺値かによらず、扱いは同じ(式中の仮引数の型は左辺値参照)だろ。
779デフォルトの名無しさん:2008/02/24(日) 23:38:46
const でない以上、壊されても文句は言えないっしょ。
780デフォルトの名無しさん:2008/02/25(月) 03:19:31
すみません、ちょっと質問です。

あるstaticメンバ関数が指定のクラスに所属しているのかを見分ける方法はありますか?

struct A {
   static void a() {};
   static void ab() {};
}
struct B : public A { static void ab() {}; }
// メンバ関数がBに属するのかどうかを知りたい
some_check_method<B, B::ab>() // true
some_check_method<B, B::a>()  // false

といった感じにしたいのですが……。
781デフォルトの名無しさん:2008/02/25(月) 07:18:06
>>780
そんな判別はできなさそうだなぁ。存在すらしてなければエラーになるし。
public 継承した上で、継承された名前が派生クラスのメンバと区別できるような
点が思い当たらないし。

なんでそんなことしたいのか、目的を言ってもらえればもうちょっと別の道が
ありそうな気はするんだけど
782デフォルトの名無しさん:2008/02/25(月) 20:50:21
>>778
右辺値参照引数に左辺値を普通に渡すことはできない。
明示的にstatic_castするか、右辺値参照を返す関数を経由することで渡す。
void f(X&& r);
template <class T> inline typename remove_reference<T>::type&& move(T&& x)
{ return x; } // return文に限っては引数を暗黙に右辺値にキャストする!
X x;
f(x); // error
f(static_cast<X&&>(x)); // ok
f(std::move(x)); // ok
引数が左辺値の参照渡しに「なる」のは関数テンプレートだけの特殊なルール。
例えば上のmoveに左辺値xを渡すと、TとT&&はともにX&になってしまう。
fのように右辺値参照をとる非テンプレート関数に左辺値を渡せば単にエラーになる。
783デフォルトの名無しさん:2008/02/25(月) 21:07:27
>>782
右辺値参照を取る非テンプレート関数に
キャストなしで左辺値を渡せると思いますよ
784デフォルトの名無しさん:2008/02/25(月) 22:32:42
>>782
draftには

struct A {};
A a;
A&& ar = a;

これは可能ということになってる。独立右辺値参照は
左辺値で初期化可能で関数渡しはNGということは
右辺値参照に関しては、これまでの考えが通用せず
”右辺値参照パラメータの関数の引数渡しは初期化の
セマンティクスとは異なる”
ということになるの?
785デフォルトの名無しさん:2008/02/25(月) 22:36:20
>>782
>引数が左辺値の参照渡しに「なる」のは関数テンプレートだけの特殊なルール>。 例えば上のmoveに左辺値xを渡すと、TとT&&はともにX&になってしまう。

これは、move(x)がmove<X&>(X&&& x)となり、&&&は&となるというルールだよな?
786デフォルトの名無しさん:2008/02/25(月) 22:37:55
lvalue-to-rvalue conversion がかかるんで普通に渡せるんじゃない?
static_cast とか std::move を使うのは overload の解決を制御するためだと思う。
787782:2008/02/25(月) 22:44:49
俺が間違ってた。>>786が正しい。
788デフォルトの名無しさん:2008/02/25(月) 22:59:40
>>786
ものすごく細かい話になりますけれど, N2521 読む限りでは
>>784のような例だと右辺値参照も左辺値参照も
全く同じ初期化の規則が適用されるように思われるので,
lvalue-to-rvalue conversion は適用されないんじゃないですかね?

lvalue-to-rvalue conversion があるので,右辺値で初期化できて
左辺値で初期化できないのは不自然に感じられるという意味なら
その通りだと思いますけれど.
789デフォルトの名無しさん:2008/02/25(月) 23:02:20
>>786
void f(A&& rv);

A a;
f(a);

の場合、引数渡しでコピーは発生せずに rv は a を左辺値
として扱える(rvはaの別名)ということでOK?
790デフォルトの名無しさん:2008/02/25(月) 23:05:24
>>789
OK
791デフォルトの名無しさん:2008/02/25(月) 23:20:35
void f(const A&); //@
void f(A&&); //A

A g();

A a;

f(a); //bound to @
f(g()); //bound to A

これは間違いなさそうなんだけど、もし@が無くAだけだった場合は
f(a) はエラーのような気もする。その場合は右辺値参照キャスト
f(static_cast<A&&>(a)) or f(std::move(a)) を行う必要がある。

これが正しいのかな?
792789=791:2008/02/25(月) 23:23:57
>>790
>>788を見て、>>789はNGかなと思ったんだけど、やっぱ正しいのかな?
それなら、>>791の内容は間違いで
f(static_cast<A&&>(a)) も f(std::move(a)) も必要ないな。
793788=790:2008/02/25(月) 23:27:35
>>791
>もし@が無くAだけだった場合は
f(a) はエラーにはならないということでよいと思います.

>>792
788で本筋とあまり関係ないことを書いて混乱させたみたいですいません.
>>789は適切という解釈でよいと思います.
794デフォルトの名無しさん:2008/02/25(月) 23:29:41
スコットメイヤーズとかハーブサッターとかニコライジョスティスは
新規格が出たらまた本をたくさん出すんだろうな。

出たら欲しいもの

超簡単な初心者本
The C++ Standard Library (second edition) by ジョスティス
Effective C++ (fourth edition) by メイヤーズ
Effective STL (second edition) by メイヤーズ
795デフォルトの名無しさん:2008/02/25(月) 23:31:18
ある程度の罠が減って、いくつかの罠が増えると
796デフォルトの名無しさん:2008/02/25(月) 23:31:34
>>793
いえ、ありがとうございます。
797デフォルトの名無しさん:2008/02/25(月) 23:31:43
Modern C++0x Design
798デフォルトの名無しさん:2008/02/25(月) 23:38:45
>>793
追記

A a;
A&& ar = a;
が正しくて、

void f(A&&);
f(a);
が正しくないとなると
”関数の引数渡しのセマンティクスは初期化のセマンティクスと同じである”
というこれまでの概念が崩れてしまうもんね。ちょっと安心した。
799デフォルトの名無しさん:2008/02/25(月) 23:41:07
>>797
それは正直もういい。Singletonなんて考えすぎだろ。
800デフォルトの名無しさん:2008/02/25(月) 23:42:44
確かにフェニックスパターンにはワラタ
あれは考えすぎ
801デフォルトの名無しさん:2008/02/25(月) 23:43:10
Modern C++0x using mpl (first edition) by ジョスティス

なら欲しい。
802デフォルトの名無しさん:2008/02/25(月) 23:47:08
小規模アロケータがデフォルトアロケータよりも遅かった
という実験結果もWebに載ってたな。Efficient C++の
シングルスレッド版は試したが確かに速かった。バグがあって
ちと苦労したが。
803780:2008/02/25(月) 23:47:24
>781

理由は、
 「ファクトリー関数を使用すると決めたけれども、派生クラスで関数の実装を強制できないと不安」
ということです。
#実際にはファクトリー関数みたいなものですが。

派生クラスを作成したときに必ずどこかでミスりそうなので、もしトラップする方法があったら
予防線を張っておこうかと考えました。
804デフォルトの名無しさん:2008/02/25(月) 23:52:21
>>803
ちょっと出来るかどうか試してくる
805デフォルトの名無しさん:2008/02/25(月) 23:55:49
>>804
風呂入ってていい?
806デフォルトの名無しさん:2008/02/25(月) 23:56:32
溺れてら
807804:2008/02/25(月) 23:57:38
>>805
runtime check で良いなら関数へのアドレス調べればよいだけだと思ったんですが

#include <iostream>

struct A
{
static void a() {}
static void ab() {}
};

struct B : public A { static void ab() {} };

int main()
{
std::cout << (&A::a == &B::a) << std::endl;
std::cout << (&A::ab == &B::ab) << std::endl;
}

compile-time check が要ったりしますか?
808805:2008/02/26(火) 00:04:20
>>807
おれは>>780ではない。
どんなキモいコードが出てくるか楽しみだったんだが。
809デフォルトの名無しさん:2008/02/26(火) 00:32:21
& 体育座り
810804:2008/02/26(火) 00:39:50
うーん, compile-time check でメンバが存在しなくてもエラーにならないのを
考えてみましたけれど, MSVC7.1 では内部コンパイラエラーになる……orz
GCC4.1.2 では通るんですが……

#include <iostream>

struct A
{
//static void a() {}
static void ab() {}
};

template<class C>
char (&has_a_helper(int))[sizeof(&C::a)];

template<class C>
char (&has_a_helper(...))[sizeof(void (*)())+1];

template<class C>
char (&has_ab_helper(int))[sizeof(&C::ab)];

template<class C>
char (&has_ab_helper(...))[sizeof(void (*)())+1];

int main()
{
std::cout << sizeof(has_a_helper<A>(0)) << std::endl;
std::cout << sizeof(has_ab_helper<A>(0)) << std::endl;
}
811デフォルトの名無しさん:2008/02/26(火) 00:45:47
struct A
{private: //←追加
static void a() {}
static void ab() {}
};

struct B : public A { static void ab() {} };
でなんか問題アルの?
812780:2008/02/26(火) 01:05:48
>807
手動で関数へのアドレスを確認するのは面倒な気が……

>811
struct Aが使い物にならなくなります……。

一応、「登録したクラスと関数が一対一になっているかどうかを判別する」というところまでは
下記のコードで実現しています。
あくまで一対一対応の判別なので、クラススコープ内の関数かどうかは判別できませんが……
      unsigned int count() {
         static unsigned int r(0);
         return r++;
      };
      template<class type_t> unsigned int number() {
         static unsigned int r(count());
         return r;
      };
      template<typename member_t, member_t member> unsigned int number(unsigned int n) {
         static unsigned int r(n);
         return r;
      };
      template<class type_t, typename member_t, member_t member> static bool check() {
         static unsigned int n(number<member_t, member>(number<type_t>()));
         return (n==number<type_t>());
      };
      struct A { static void a() {}; static void ab() {}; };
      struct B : public A { static void ab() {}; };
      BOOST_CHECK_EQUAL((check<A, void(*)(), A::ab>()), true);
      BOOST_CHECK_EQUAL((check<B, void(*)(), B::ab>()), true);
      BOOST_CHECK_EQUAL((check<A, void(*)(), A::a>()), true);
      BOOST_CHECK_EQUAL((check<B, void(*)(), B::a>()), false);
ちなみに、このコードに興味ある人います?いるんでしたらフロ入った後に解説書きますけど。
813デフォルトの名無しさん:2008/02/26(火) 02:07:33
よくわからんなー。struct Aは要するにインターフェースで、
static voidなa,abは要するに仮想関数なわけでしょ?
で、オーバーライド必須にしたい、みたいな。
 それのテンプレート版、という話と理解したけど、
ならNVIイディオム使えば終わる話じゃねーの?
814780:2008/02/26(火) 02:16:16
いや、>803にも書いたけど
 「ファクトリー関数を使用すると決めたけれども、派生クラスで関数の実装を強制できないと不安」
ということですね。struct Bからさらに派生する場合も対応できるようにしたいです。
あとstaticメンバ関数は仮想にできないのでNVIはムリですね。
815デフォルトの名無しさん:2008/02/26(火) 07:09:37
>>812
解説希望。
816デフォルトの名無しさん:2008/02/26(火) 07:22:34
>>814
正直どういう風に使いたいのかよく分からん。
どういう風な事がやりたいのかとりあえずコード書いてくれ。
コンパイル通らなくてもいいから。
817デフォルトの名無しさん:2008/02/26(火) 18:08:19
すみません、質問お願いします。

下のコードでパターン1と2をコメントアウトで切り替えると速度が大きく変わります。
原因わかる方いらっしゃいますか?

for( i = 0; i < 1200000; i++ )
{
*(pDst + 0 ) = *(pSrc + 0);
*(pDst + 300) = *(pSrc + 1);
*(pDst + 600) = *(pSrc + 2);
*(pDst + 900) = *(pSrc + 3);

pSrc += 4;

// パターン 1
pDst += 1200; // こっちだと60msくらいかかる

// パターン 2
pDst += 300; // こっちだと17msで終わる
}
818デフォルトの名無しさん:2008/02/26(火) 18:13:36
メモリのヒット率?
819デフォルトの名無しさん:2008/02/26(火) 18:19:13
>>817
環境が判らんから何とも言えんが、恐らくは>818。
しかし、何でまたそんな小汚いコードを書いているんだ?
普通にpDst[900] = pSrc[3]と書けばいいものを。
820デフォルトの名無しさん:2008/02/26(火) 18:20:55
>>817
そこだけならキャッシュのヒット率だと思うけど…
LinuxでIntelのx86使ってるならVTuneがタダで使えるよ
821デフォルトの名無しさん:2008/02/26(火) 18:55:21
1200 * 1200000 = 1440000000 だけど、
そんなにメモリ確保してあるの?

確保してるとしても、ページフォールト起こしそう。
キャッシュよりそっちのが問題かもしれない。
822デフォルトの名無しさん:2008/02/26(火) 19:23:41
みなさん回答ありがとうございます。
メモリのヒット率ですか・・・
そうだとするとここから先の高速化は難しそうですね・・・

ちなみに環境は以下の通りです。
Intel Core Duo T2500
メモリ1GByte
WindowsXP
VisualC++6.0

>>821
>1200 * 1200000 = 1440000000 だけど、
>そんなにメモリ確保してあるの?
ごめんなさい間違っていました。
1200000ではなく、300000です。
メモリは物理メモリ内に確保できています。
823805:2008/02/26(火) 20:26:04
ビョーン・ストラウストラップ氏はどこの国の人ですか?
824デフォルトの名無しさん:2008/02/26(火) 20:28:39
ビャーネ・ストロヴストルップ(Bjarne Stroustrup, 1950年6月11日 - )は、
デンマーク・オーフス生まれのコンピュータ科学者。
825デフォルトの名無しさん:2008/02/26(火) 20:38:03
>>824
thx
デンマークか。C++はアメリカ発信じゃないのがいい。
826デフォルトの名無しさん:2008/02/26(火) 20:47:46
でも、C++はベル研生まれでアメリカ発信でそ?
827デフォルトの名無しさん:2008/02/26(火) 20:53:33
ヨーロッパはやっぱりレベル高いよな。フィンランドとか凄いらしいな。
828デフォルトの名無しさん:2008/02/26(火) 21:24:09
>>814
ファクトリーをstaticメンバ関数じゃなく関数テンプレートの特殊化にするのはダメ?
template <class T> T *factory();
class Base {
    friend Base *factory<Base>();
protected:
    Base();
    virtual ~Base();
};
class Derived : public Base {
    friend Derived *factory<Derived>();
protected:
    Derived();
    virtual ~Derived();
};
829デフォルトの名無しさん:2008/02/26(火) 21:39:06
sizeof(空のクラス) = 1;
sizeof(空の構造体) = 1;

なぜ0バイトでなく、1バイトになるんでしょうか?
830デフォルトの名無しさん:2008/02/26(火) 21:52:53
FAQ: EmptyRect kara[4];とかやってインスタンス化したとき、
サイズが0だと&kara[0] == &kara[3]とかになっちまってまずい。
831デフォルトの名無しさん:2008/02/26(火) 21:55:41
>>829
複数のオブジェクトを作ったときにオブジェクトして何らかのサイズを持って
存在していないとuniqueなオブジェクとしてトアドレスが決まらない。
詳しくはInseide The C++ Object Modelに載ってる。
832デフォルトの名無しさん:2008/02/27(水) 03:03:34
C++のSTLは便利なんですけど、
一行が助長に長くなってしまって耐えられません。
833デフォルトの名無しさん:2008/02/27(水) 03:43:25
"助長に長く"の検索結果 2 件中 1 - 2 件目 (0.44 秒)
834デフォルトの名無しさん:2008/02/27(水) 03:50:37
>>832
typedefを程よく使うしかないね。「程よく」ってのがまぁ、人それぞれなんだけど。

typedef std::vector<MyClass>::const_iterator Iter;
for (Iter i = vec.begin(); i != vec.end(); ++i) {
なんてのは、結構やる人多いはず。
Iterがこれ以降出てこない場合、このtypedefは全体としては「短縮」にも「簡略」にも
なっていないわけだけど、それでも「forの行を短く見せたい」というだけの理由で、俺はよくこう書いてる。
もちろん人によっては、「程よく」の範囲を超えた、余計な足踏みみたいに感じるのだろうけどね。

> 助長に長くなってしまって
このレス書き込む前にリロードしたらもう突っ込まれていたので、突っ込むのやめるw
835デフォルトの名無しさん:2008/02/27(水) 04:12:49
C++0xのautoなら・・・いやなんでもない
836デフォルトの名無しさん:2008/02/27(水) 06:04:48
言いかけて引っ込める意味がわからん。
837デフォルトの名無しさん:2008/02/27(水) 07:33:06
態々それだけのためにレスをつける意味がわからん。

それはさておき、1行の長さを抑えるためにもインデントは4カラムにするのが定着した私。
>834みたいなことをすると、同じブロック内で別のイテレータ使いたくなるときに困ると思う。
838デフォルトの名無しさん:2008/02/27(水) 09:13:29
ITE!救命阿!
839デフォルトの名無しさん:2008/02/27(水) 10:47:03
#include <iostream>
#include <vector>

int main()
{
std::vector<int> v{ 1,2,3,4,5 };
for(auto i = v.begin(); i < v.end(); ++i)
std::cout << *i << std::endl;
}
840デフォルトの名無しさん:2008/02/27(水) 12:44:21
BOOST_FOREACH()おいしいです
841デフォルトの名無しさん:2008/02/27(水) 12:53:36
>>839
間違った

i != v.end()
842デフォルトの名無しさん:2008/02/27(水) 14:03:58
>>840
C++0xのSTLには採用されるのか?
843デフォルトの名無しさん:2008/02/27(水) 14:09:07
>>842
禿が生きてる限り、標準ライブラリにプリプロセッサ使ったブツは追加されないんじゃね。
必要だってことになったら、言語に組み込む方法に持っていかれるだろ。
844デフォルトの名無しさん:2008/02/27(水) 14:17:12
>>843
そういやマクロだからな
言語に組み込むなら、もっと詳細を詰める必要がありそうだな。
845デフォルトの名無しさん:2008/02/27(水) 20:00:07
for (int x : v)のような構文でC++0xへ提案があったはず。
846デフォルトの名無しさん:2008/02/27(水) 20:04:16
847デフォルトの名無しさん:2008/02/27(水) 20:24:16
>>846
結局、今のところはなし?
848デフォルトの名無しさん:2008/02/27(水) 20:57:57
とりあえずまだ最新ドラフトには載ってない。
849デフォルトの名無しさん:2008/02/27(水) 21:06:12
>>848
n2461か?
850デフォルトの名無しさん:2008/02/27(水) 21:10:06
実は n2521 が出てる。
851デフォルトの名無しさん:2008/02/27(水) 21:18:21
>>850
間違えた
それ落としてた
852デフォルトの名無しさん:2008/02/27(水) 21:36:24
vc は独自拡張で for each なんて作っちゃってるよな
853デフォルトの名無しさん:2008/02/27(水) 21:38:08
C++/CLIをVCの独自拡張とか言わないで欲しい
854デフォルトの名無しさん:2008/02/27(水) 21:39:00
C++/CLIはVCの独自拡張。間違いない。
855デフォルトの名無しさん:2008/02/27(水) 21:46:11
for eachはC++/CLI関係なく、ネイティブC++でも使用できる。
これは、C++でもC++/CLIでもないのだからVC++の独自拡張としか言えない。
856デフォルトの名無しさん:2008/02/27(水) 21:56:11
むしろ独自拡張以外になんとお呼びすればよいのでしょうか的な
857デフォルトの名無しさん:2008/02/27(水) 22:17:54
方言。
858デフォルトの名無しさん:2008/02/27(水) 22:53:11
foreachとかrangeとか、ちょっと節操無さすぎだと思う。
今のC++への不満を直球で解決しようとしてるだけで、
STLが目指してきたものを蔑ろにしている。
autoとλを組み合わせて制御構造そのものはいじらないのが
正常な進化の方向だと思う。
859デフォルトの名無しさん:2008/02/27(水) 23:24:30
#include <iostream>
namespace{
void foo(){ std::cout << "anonymous foo" << std::endl; }
}
void foo(){ std::cout << "global foo" << std::endl; }

int main(void)
{
//foo(); //コンパイルエラー
::foo(); //global foo
}
ここで無名名前空間のfooを明示的に呼ぶ方法はあるんでしょうか
860デフォルトの名無しさん:2008/02/27(水) 23:29:29
ない
861859:2008/02/28(木) 00:46:45
まじすか・・・
862デフォルトの名無しさん:2008/02/28(木) 01:23:13
無名名前空間って、staticの代わり以外に使い道ある?
863デフォルトの名無しさん:2008/02/28(木) 02:59:44
>>862
ファイルローカルなクラスや列挙体を囲って ODR 違反を回避する。
864デフォルトの名無しさん:2008/02/28(木) 12:48:23
namespace_start.hpp------
namespace{

namespace_end.hpp------
}


#include "namespace_start.hpp"
//...
#include "namespace_end.hpp"
865デフォルトの名無しさん:2008/02/28(木) 19:49:35
>>862
Koenig lookup対策
866デフォルトの名無しさん:2008/02/28(木) 19:53:10
>>863
それってつまりどういうこと?
kwsk!!
867デフォルトの名無しさん:2008/02/29(金) 01:24:02
>>866
// A.cpp
struct X { char x; };

// B.cpp
struct X { char y; };

両方コンパイルしてリンクすると同じクラスに対する2つの定義が異なるという
ODR 違反になり、未定義動作となる。

それぞれ無名名前空間で囲っておけば別々のクラスになるので問題なくなる。
868デフォルトの名無しさん:2008/02/29(金) 02:25:40
class MyClass
{
private:
int a;
double b;
char c;
public:
MyClass(int, double);
~MyClass();
void Func(int);
};

int main()
{
MyClass myclass;
myclass = MyClass(1, 2.0);
}

とした場合、myclass = MyClass(1, 2.0)は引数にある変数だけがコピーされるんですか?
それともコンストラクタを実行した後のクラスの中身が全部コピーされるんですか?
869デフォルトの名無しさん:2008/02/29(金) 02:29:21
代入演算子はデフォルトの動作はビットコピーだから
870デフォルトの名無しさん:2008/02/29(金) 09:38:19
>>868 後者。
>>869 ちがうよ。
871デフォルトの名無しさん:2008/02/29(金) 11:39:50
>>869
各メンバに対してoperator=を呼ぶんだと思ったが
872デフォルトの名無しさん:2008/02/29(金) 14:23:35
どなたかわかる方いれば教えてください。
CE環境のプログラム上で、プログラムカウンタを参照する方法ってありませんか?
873デフォルトの名無しさん:2008/02/29(金) 14:53:55
関数テンプレートHogeがあるとします。
HogeはT型のオブジェクトtを引数で受け取り、そのオブジェクトのメンバ関数Fugaを呼び出します。

ここで、Hogeに渡したtがFugaを持ってない場合、コンパイルエラーになりますが、
コンパイルエラーにせず、Fugaを呼び出さない別の実装に転送する方法はないでしょうか?
874デフォルトの名無しさん:2008/02/29(金) 15:10:40
>>873
SFINAE
875デフォルトの名無しさん:2008/02/29(金) 15:13:44
>>872
extern int* puroguramu_caunta asm ("pc");
使えるかどうかはしらね
っつうかスレ違い
876デフォルトの名無しさん:2008/02/29(金) 15:14:01
>>873
コンパイル時に実装を切り替えるというのは、変態がよく使う。
本当にさまざまな方法がある。
例えば関数のオーバーロードとか、テンプレートクラスの特殊化など
詳しく知りたかったら、C++ Template Metaprogrammingを読め。

で、ある名前のメンバ関数を持っているかどうかってのは、
かなりトリッキーなコードになるので、もっとマシな方法で実装分岐させたほうがいい。
877876:2008/02/29(金) 15:17:45
まさにこのスレで、その話題でたのを忘れてた。

>>873
そのトリッキーなコードの一例が>>261
878デフォルトの名無しさん:2008/02/29(金) 15:25:23
>>875
ありがとうございます。
試してみます。
スレ違いになるのね…
すみませんでした。
879デフォルトの名無しさん:2008/02/29(金) 15:36:20
880デフォルトの名無しさん:2008/02/29(金) 15:45:33
>>877
C++ Template Metaprogrammingってよお、買ったけどboost::mplの
リファレンスじゃねーか。Webサイト見たほうがいいわ。
騙された。
881873:2008/02/29(金) 15:59:28
>>874,876
どうもです。
省略符号を使ったテクニックがあったんですね。

C++ Template Metaprogrammingは読んでいませんが、Modern C++ Designは読んだので大体分かります。
省略符号を使って変換可能性と継承を検出するテクニックも書いてありましたね・・。
テンプレートに関数ポインタ渡してメンバ関数の有無検出する方法、思いつかなかったorz
882デフォルトの名無しさん:2008/02/29(金) 16:07:44
>>876
>で、ある名前のメンバ関数を持っているかどうかってのは、
>かなりトリッキーなコードになるので、もっとマシな方法で実装分岐させたほうがいい。

トリッキーでもいいけどC++ Template Metaprogrammingって本に何か例が書いてあるの?
883デフォルトの名無しさん:2008/02/29(金) 16:19:32
>>882
>>873がどの程度C++を知っているのか分からなかったから、出してみただけ。
ある名前を持つメンバ関数でコンパイル時の分岐がやりたいなんていいだす奴は、
そもそも何も分かってないバカか、本当に自分が言っている事を理解していて、それでもやりたい変態しかいない。
Modern C++ Desingを枕にするぐらいだったら、必要なかったね。
884デフォルトの名無しさん:2008/02/29(金) 16:29:57
placement newで生成した配列データってどう解放すればいいんでしょうか?

void *pvMem = AllocMemory(sizeof(CNode) * num);
CNode *pcNodes = new(pvMem) CNode[num];

for(int i = 0; i < num; i++)
{
pcNodes[i].~CNode();
}

FreeMemory(pcNodes);

これだとダメみたいです。
885デフォルトの名無しさん:2008/02/29(金) 16:45:48
placement deleteは呼ばなくてもいいんかい?
886デフォルトの名無しさん:2008/02/29(金) 16:49:18
>>884
AllocMemory
FreeMemory

ここで何やってるんだ?
887デフォルトの名無しさん:2008/02/29(金) 16:49:30
>>884
×FreeMemory(pcNodes);
○FreeMemory(pvMem);
888デフォルトの名無しさん:2008/02/29(金) 17:10:19
>>884
普通、
void FreeMemory(void*);
のシグニチャだと思うけど。
それなら、それでも良いはずなんだが。
889デフォルトの名無しさん:2008/02/29(金) 17:11:18
>>885
FreeMemoryでメモリ解放するの特に必要ないかと思って・・・

>>886
AllocMemory(size)
sizeだけメモリを確保

FreeMemory(p)
pが先頭のメモリブロックを解放する

>>887
それもダメでした
890885:2008/02/29(金) 17:12:51
すまん、placement deleteは関係ないや。
(Effective C++ Item52)
891デフォルトの名無しさん:2008/02/29(金) 17:15:52
>>889
>AllocMemory(size)
>sizeだけメモリを確保
特別なメモリ確保のライブラリか何か?

AllocMemoryでnew演算子を使用
FreeMemoryでdelete演算子を使用

なんてことじゃないよね?

892デフォルトの名無しさん:2008/02/29(金) 17:22:23
>>884
new するときもひとつずつ placement new するしか無いんでは・・・
893デフォルトの名無しさん:2008/02/29(金) 17:23:28
>>891
>特別なメモリ確保のライブラリか何か?
そうです。提供されているもので自作ではありません。ここでは関数名は変えて書きましたが。

>AllocMemoryでnew演算子を使用
>FreeMemoryでdelete演算子を使用
size分メモリ確保してるだけなのでnew,deleteはしていません。
894デフォルトの名無しさん:2008/02/29(金) 17:24:34
>>884
AllocMemory(size)でreturn operator new(size);

FreeMemory(p)でoperator delete(p);

と思っていい?

895デフォルトの名無しさん:2008/02/29(金) 17:24:37
>>892
そうなんですかね・・・。なんてこった

実はちょっと前にそっちのやり方で作ってたんですけど、確かにそれはきちんと動いていました。
896デフォルトの名無しさん:2008/02/29(金) 17:25:15
>>894
それで解釈してもらってけっこうです
897デフォルトの名無しさん:2008/02/29(金) 17:46:35
VCでも似たような状況が再現できました。対処法はわかりませんが

#include <iostream>
#include <new>

class CNode
{
public :
int temp[3];

public:
CNode(){ Init(); }
virtual ~CNode(){}

public :
void Init(){ temp[0] = 0; temp[1] = 1; temp[2] = 2; }
};

#define PLACEMENT_NEW 0
898デフォルトの名無しさん:2008/02/29(金) 17:46:56
つづき

int main()
{
char *buf = new char[sizeof(CNode) * 3];

#if PLACEMENT_NEW
CNode *pcNode = new(buf) CNode[3];
#else
CNode *pcNode = reinterpret_cast<CNode*>(buf);
for(int i = 0; i < 3; i++)
{
pcNode[i].Init();
}
#endif

#if PLACEMENT_NEW
for(int i = 0; i < 3; i++)
{
// placement newをやっていないと落ちる
pcNode[i].~CNode();
}
#endif

// PLACEMENT_NEW=1のときは落ちない
delete [] buf;

return 0;
}
899デフォルトの名無しさん:2008/02/29(金) 17:49:46
>PLACEMENT_NEW=1のときは落ちない
PLACEMENT_NEW=0のtきは落ちない、でした
900デフォルトの名無しさん:2008/02/29(金) 17:53:23
確かサイズ指定しなきゃダメじゃなかったけ?
そのせいで使い物にならなかった気がする。
901デフォルトの名無しさん:2008/02/29(金) 18:00:47
>>900
ちょっとよくわかりません。もう少し詳しくお願いします
902デフォルトの名無しさん:2008/02/29(金) 18:07:59
placement newに対しては、placement deleteを呼ばないといけない。
ちゃんとなってる?

CNode::operator delete( p, buf );
903デフォルトの名無しさん:2008/02/29(金) 18:08:21
>>898
ちょっとまて、placement newしているかどうかにかかわらず、
delete[]が呼び出されるのは何なんだ?
placement newしているポインタに、delete[]したら、鼻から悪魔が出てくるのは当たり前だろ。
あと、placement newしていない場合のコードも鼻から悪魔が出るな。
904デフォルトの名無しさん:2008/02/29(金) 18:19:49
>>884
ところで、placement new[]に渡されるsizeはsizeof(T)*Nとは限らないぞ。
そこでメモリ破壊してるんじゃねえの。
905デフォルトの名無しさん:2008/02/29(金) 18:41:10
>>904
ttp://www.fides.dti.ne.jp/%7Eoka-t/cpplab-placement-new-3.html
ここのサイトに似たようなことが書いてあったので試しました。

VCではsizeof()*n+4でハングしなくなりましたが、元々の環境ではやっぱりハングしました。
906デフォルトの名無しさん:2008/02/29(金) 18:43:43
>>905
ロベールのC++入門講座嫁
907デフォルトの名無しさん:2008/02/29(金) 18:56:25
ちょっと出直してきます。
いろいろ参考になりました。ありがとうございました
908デフォルトの名無しさん:2008/02/29(金) 20:29:04
>>906

AllocMemory -> operator new(size_t) を使用
FreeMemory -> operator delete(void*) を使用
と思われる。(AllocMemoryのシグニチャでは要素数が判別できないので
内部でoperator new[](size_t)を使用することは難しい)

で、

CNode *pcNodes = new(pvMem) CNode[num];

これはマズイ。

配列用の配置newはCNodeクラスのデフォルトコンストラクタ
をnum回実行する。実装に依存するけど、例えば次のようなことが
考えられる。sizeof(delta)を配列の要素数などの管理情報を確保して
おくための領域のサイズとすると、アドレスpvMemからpvMem + sizeof(delta)
の領域に管理情報を書き込み、最初のコンストラクタはアドレス pvMem + sizeof(delta)
に対して実行される。そして最後のコンストラクタはsizeof(delta)バイトだけ
飛び出した未確保の領域まで初期化してしまう。

結局、非配列用のoperator new(size_t)の戻り値のアドレスに配列用の配置newを
使用することは危険。pvMemを自分で管理して、配列用ではない配置newをnum回実行
して初期化すべきかと。

>>905
ご使用のVCでは管理情報の領域として4バイトが使用されているのかも。
元々の環境では、違うサイズ、あるいは全く異なる実装で配列が管理
されてるのかも。
909デフォルトの名無しさん:2008/02/29(金) 20:29:59
レス番間違えた。

>>906

ではなく

>>907
910デフォルトの名無しさん:2008/02/29(金) 22:26:37
>>902
そんなことない。 placement delete はコンストラクタで例外が発生したときに呼ばれるだけ。

<new> で宣言される void* をひとつ受け取る placement new に対しては t.~T() で
デストラクタを呼び出すだけにするのが正解。これの配列バージョンは >908 が挙げた
とおりあらかじめ用意しておくべきサイズをコンパイラしか知らないので、使うのが
難しい。

476. Determining the buffer size for placement new
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#476
911デフォルトの名無しさん:2008/02/29(金) 23:18:39
>261 のリンク先にもあるんだけどさ

>SFINAE allows you to determine type information at compile-time through the usage of overload resolution.
>However, it cannot prevent non-type syntax errors. An example of which you have demonstrated in your code.
>The class member T::Foo does not exist, nor is it a type, as such SFINAE does not apply here.

規格上で SFINAE の根拠になるのは 14.8.2/2 だと思うんだけど、U::Hage はそこで挙がってる type deduction の失敗の例には
入らないので syntax error を引き起こすと思うんだが。いやコンパイル通っちゃったんだけどさ。


で、placement new についてだけど、>887 と >904 他が正しいと思われる。
> 5.4.3/12
> new T[5] results in a call of operator new[](sizeof(T)*5+x), and
> new(2,f) T[5] results in a call of operator new[](sizeof(T)*5+y,2,f).
> Here, x and y are non-negative unspecified values representing array allocation overhead; the result of the
> new-expression will be offset by this amount from the value returned by operator new[]. This overhead
> may be applied in all array new-expressions, including those referencing the library function
> operator new[](std::size_t, void*) and other placement allocation functions. The amount
> of overhead may vary from one invocation of new to another.
912デフォルトの名無しさん:2008/02/29(金) 23:45:47
class Holder.....Impl のポインタを持ち、Holder() : m_pImpl(new Default_Impl()){}
class Impl.....抽象クラス
class Default_Impl.....Impl を public 継承 std::vector<Holder> を持つ

これで、Holderのインスタンス作ったらオーバーフローになってしまいました。
調べてみたら、
1, Holder のコンストラクタ
2, Default_Impl のコンストラクタ
3, std::vector<Holder> のアロケータ
4, Holder のコンストラクタ
以下ループ

っということらしいのですが、
どういう設計にすれば上のようなクラスを問題なく作成できるのでしょうか。
913デフォルトの名無しさん:2008/02/29(金) 23:47:49
>>912
やりたいことが間違ってるだけにしか見えん。
違うというのなら何がやりたいのか説明してくれ。
914デフォルトの名無しさん:2008/02/29(金) 23:55:35
>>913
これ以外に、関数ポインタを受け取れる Func_Impl があって、
Holder(void (*func)(Arg)) : m_pImpl(new Func_Impl(func)){}
のようにHolderを作成できて、

Default_Impl で作ったHolderは上記のような関数を保持するHolderと、
それを複数保持するDefault_Implを保持するHolderを保持したくて、

Holderの operator() で保持してる関数全てを実行するようなクラスを作りたいと思っています。
915デフォルトの名無しさん:2008/02/29(金) 23:59:05
>>914
なんで Default_Impl のコンストラクタで引数無しの Holder を生成してるの?
916デフォルトの名無しさん:2008/03/01(土) 00:06:34
>>915
>>Default_Impl で作った
は、
Default_Impl を保持するHolder(引数なしHolderのコンストラクタから生成)

でした。紛らわしい表現をしてすみません…。

理想としては
Holder holder;
holder.add(Holder(関数ポインタ1));
holder.add(Holder(関数ポインタ2));
holder.add(holder2); // 別のHolder
holder(); // 全ての関数を実行

という動作をさせたいと思っています。
917デフォルトの名無しさん:2008/03/01(土) 00:11:15
>>875
一体何のためにPCなんか参照したいんだ?
918デフォルトの名無しさん:2008/03/01(土) 00:12:54
>>911

<new>で定義されてるグローバルの配置operator new(size_t, void*)関数である
new(pvMem) CNode[num]; については、pvMemをreturnしてるだけ。
その後で、コンストラクタが必要な回数だけ実行される。その際、配列の管理が
コンパイラ依存で行われる。
>>904は一般的な配置newについて正しいが、このケースでは<new>のものを使用している
ので>>908>>910が上手く表現している。
919デフォルトの名無しさん:2008/03/01(土) 00:37:47
>918
とりあえず placement new で領域割り当ててるわけじゃない、という点については >908 の方がより的確なのかもしれないけど。
必要なサイズは sizeof(T)*N じゃない、ぐらいの気持ちで。
もともとの placement new の位置づけからすればこっち(別の割り当て済みメモリ領域にオブジェクトを生成する)の方が主な
使い方の気もするけど、AllocMemory とか FreeMemory に突っ込みが入るようだとあまり一般的じゃないのかなぁ。

で、どっちかというと >887 で指摘されてる点があんまり言及されてないのが気になって。
<new> で規定されてるのは allocation function であって、それ自体は単に渡された値を返していたとしても、
new 演算子の結果 new(pvMem) CNode[num] については、allocation fuction から返ってきた値そのままではないよね?
920デフォルトの名無しさん:2008/03/01(土) 00:52:14
>>916
だからさ、 Default_Impl のコンストラクタで引数無しの Holder を生成しなくても
できるだろ。なんでわざわざ生成して当然の無限再帰を引き起こすのさ?
921868:2008/03/01(土) 01:11:57
>>869
なるほど、ありがとうございました。
922デフォルトの名無しさん:2008/03/01(土) 01:16:31
>>920
std::vector<Holder> を初期化するときにHolderのコンストラクタが呼ばれる、ということでしょうか

呼び出し履歴からHolderの引数なしコンストラクタが呼ばれているのは分かったのですが、
Default_Impl のどこで呼ばれているのかとその対策が分からず困っています。

具体的にDefault_Impl の実装のどこが間違っていて、どう対処すればいいのか、
ヒントだけでも教えていただけると助かります。
923デフォルトの名無しさん:2008/03/01(土) 01:17:25
>>921 違うっつってんだろ
924デフォルトの名無しさん:2008/03/01(土) 01:18:16
>>922
Default_Impl の実装を見せずにその間違いを指摘しろとは、エスパーでも募集してんのか?
925912:2008/03/01(土) 01:29:04
>>924
実際の物とは違いますが、こちらでも同じ現象が起きてしまいます。
Default_Impl のコンストラクタでは、vector<Holder> の初期化しか行なっていないのですが…

http://sourcepost.sytes.net/sourcepost/sourceview.aspx?source_id=30119
926デフォルトの名無しさん:2008/03/01(土) 01:32:10
>>925
> Default_Impl() : m_holder(0) {}

vector(size_type n, value_type const& x = value_type()) が呼ばれてる。
空でいいなら m_holder() でもいいし、何も書かずにデフォルトの初期化に
してしまってもいい。
927868:2008/03/01(土) 01:34:27
すみません。アンカーミスです。
>>870でした。
928デフォルトの名無しさん:2008/03/01(土) 01:36:56
>>925
vector<Holder>(0)は、2つの省略可能な引数を持つコンストラクタを読んでる。
そこで、Holder()が生成される。
929デフォルトの名無しさん:2008/03/01(土) 01:49:02
>>926, 928
ありがとうございます、無事実行することが出来ました
vector(0) でコンストラクタが呼ばれるはずがない、
という勝手な思いこみで要領を得ない質問ばかりしてしまいましたが、
回答をいただけてとても助かりました。
930デフォルトの名無しさん:2008/03/01(土) 02:13:47
>>919

><new> で規定されてるのは allocation function であって、それ自体は単に渡された値を返し>>ていたとしても、 new 演算子の結果 new(pvMem) CNode[num] については、allocation fuction
> から返ってきた値そのままではないよね?

実装依存なので絶対とは言えないけど、ほとんどの実装でそうなっていると思える。
おそらくは配列の要素数を格納するための領域分ずれてる。
実際、配列の要素数は配置new演算子に渡されたアドレスの直後に置かれることが多い。
でも、あくまでも実装依存であって規格では未定義。

でも問題はそれ以前であって、強調したかったのは、規格に従う限りにおいては、
AllocMemoryが戻すアドレスpvMemを配列用の配置構文newに new(pvMem) CNode[num]
のように渡すことさえ問題が起こりうるということ。何故なら、要素数がどこに書
き込まれるかは分からないから。実装を熟知し(配列の管理情報は本当に要素数だけか?
渡すべき正しいアドレスは何か?)、移植性を考えないという条件でのみこれは許され
ることになる。つまるところ、>>908>>910のドキュメントどおり、ユーザーが確保した
領域に対して配列用の配置構文newを使うことは難しく、常に危険を伴っている。
配置構文newにどのアドレスを渡してよいかは厳密に言うと実装を知らないと判断できない。
931780:2008/03/01(土) 03:45:16
>815
遅くなりましたが解説書きました。
ttp://fiercewinds.net/siki/pub/2008/03/01_032951/
基底クラスで登録洩れがあると破綻するから、嬉しさも中ぐらいだなぁ。
あと、ファクトリー関数の場合は共変の戻り値を使う=関数に指定クラスが含まれることが多いので、
ここまで面倒臭いことしなくても簡単にコンパイルエラーに持って行けそうな感じがします。……試さないけど。
932デフォルトの名無しさん:2008/03/01(土) 05:15:20
思ったんだが、C++で生のC配列なんか使う
メリットないだろ。

配列用の配置構文が使い物にならんのは
つまりそういうこと。


933デフォルトの名無しさん:2008/03/01(土) 09:45:52
そもそも設計がおかしくないか?
934デフォルトの名無しさん:2008/03/01(土) 11:52:04
>>932
つまらないこと言うなよ。
やるなと言えばそれまでだが、やったらどうなるの?
に対する回答にはならん。
935デフォルトの名無しさん:2008/03/01(土) 14:47:10
>>917
あとから確認するときに、場所を特定するために残しておきたいんです。
936デフォルトの名無しさん:2008/03/01(土) 15:54:47
>>934
明らかに回答ではないんだから(現在の話題に関して「思ったこと」を書いてるだけ)、
別に回答になっていなくても問題は無いと思うよ。

質問から始まった話題について何か書き込む時は、絶対に回答としての機能を
持っていなければならない、という信念があるとしたら、もうちょっと柔軟になったほうが・・・。
937デフォルトの名無しさん:2008/03/01(土) 17:09:41
規格では未定義=
もしそのコードを実行してしまったら何が起こるか予測できないって事

placement new
は将来のために予約されたものだと俺は思ってるから
積極的に使うものじゃないと思う。

コレ使ってるライブラリって見たことない。
938デフォルトの名無しさん:2008/03/01(土) 17:46:29
>>937
std::allocatorのconstruct
939デフォルトの名無しさん:2008/03/01(土) 18:35:31
C++0xでアラインメントをサポートするんじゃなかったっけ

そうなれば多少マシになるんじゃないの
940デフォルトの名無しさん:2008/03/01(土) 18:56:23
>>938
サンクス

ユーザレベルなら

std::allocator
boost::pool_allocator

あたり使ったほうがいいですよね?

941デフォルトの名無しさん:2008/03/01(土) 19:00:45
>>940
placement new 使いたいためにわざわざ std::allocator の construct 使うの?
なんで? placement new 使えばいいじゃない。
942デフォルトの名無しさん:2008/03/01(土) 19:06:33
>>935
たとえば今のPCは、今居る関数のポインタ値にだいたい近いよね。
それじゃダメなの?
943デフォルトの名無しさん:2008/03/01(土) 19:08:08
__FILE__と__LINE__で何が不満なわけ?
944デフォルトの名無しさん:2008/03/01(土) 19:12:13
スタックトレースでもしたいんじゃないの
945デフォルトの名無しさん:2008/03/01(土) 19:21:55

ドットイートのようなゲームを作りたいんですが、
どうしてもドットを食わず、素通りしてしまいます。

自機がドットを通ると道になるようなプログラムは
どうしたらできるんでしょう?
946デフォルトの名無しさん:2008/03/01(土) 19:33:22
ドットを表す値が入っている変数に道を表す値を代入すればいいんじゃない。
947デフォルトの名無しさん:2008/03/01(土) 19:37:08
当たり判定チェックミスってんじゃね?
948デフォルトの名無しさん:2008/03/01(土) 21:35:06
>>945
今はどうやってるんだ
まずそれを説明してみろ
949デフォルトの名無しさん:2008/03/01(土) 22:20:47
template <typename T> と template<class T> といった
2種類の書き方が存在するみたいだけど、どっちも一緒ですか?
あと、使うならどっちが望ましいんでしょう。
950デフォルトの名無しさん:2008/03/01(土) 22:28:22
どっちも一緒。
template template parameter つまり template<template <typename T> class U> の時だけは class じゃないと駄目。
趣味の問題だから好きな方を使えば良い。
951デフォルトの名無しさん:2008/03/01(土) 23:42:52
template<class T>
class A
{
private:
typename T::B m_abc;
}

のときはtypenameじゃないとだめ
952デフォルトの名無しさん:2008/03/02(日) 02:45:45
600000000000を変数に入れたいんですけど、どうすればいいのか教えてください。
unsigned long int r=600000000000
だとinteger constant is too large for "long" type
といエラーが出てしまいました。
953デフォルトの名無しさん:2008/03/02(日) 02:49:33
>>952
厳密な精度が要らなければ double などの不動小数点数を使うといい。
そうじゃなければ多倍長整数を使うことになるでしょう。
954デフォルトの名無しさん:2008/03/02(日) 02:50:56
>>952
long long int int r=600000000000;
955デフォルトの名無しさん:2008/03/02(日) 02:51:28
コピペみすったorz

long long int r=600000000000;
956デフォルトの名無しさん:2008/03/02(日) 11:09:17
long long は正式には C++0x から導入されるものだろう・・・。
とはいえ、今の所規格上はそういう型はないしなあ。
まあ、規格で int が 32 ビットと決まってるわけではないから
int が 64 ビットの場合もあるわけだが。

まあ、環境によって
typedef unsigned __int64 UINT64;

typedef unsigned long long UINT64;
かを定義すればいいよ。
957デフォルトの名無しさん:2008/03/02(日) 11:54:06
まず何故そんな大きな数値を扱う必要があるのか、その理由を・・・
目的によって double, 多倍長整数, UINT64, BCD など変わってくるだろ
958デフォルトの名無しさん:2008/03/02(日) 12:26:33
>>956
つuint64_t
959デフォルトの名無しさん:2008/03/02(日) 12:33:25
だからそれも C++0x から導入される(略
960デフォルトの名無しさん:2008/03/02(日) 12:34:59
C99を取り込んでいるコンパイラなら大抵使えるけどな。
961デフォルトの名無しさん:2008/03/02(日) 13:46:11
よーしパパboost::uint64_t使っちゃうぞー
962952:2008/03/02(日) 22:36:22
>>953>>954>>956>>957>>958
ありがとうございます。参考にしてやってみます。
963デフォルトの名無しさん:2008/03/04(火) 15:41:12
>>952
コンパイラのデータモデルを調べよう
>>958のようにデータモデル別に定義してくれてるライブラリの型を使うのが安泰

代表的なのだと、gcc4がILP32,LP64、vc++がILP32,LLP64など、
組み込み系だとLP32なんて曲者もあるから困る
964デフォルトの名無しさん:2008/03/05(水) 17:18:50
class hoge を作っておいて、list<hoge> x を生成します。
そのとき、hogeのメンバ関数も使いたいのですが、STLを使った場合だと
x.piyo()みたいではアクセスできません。 どうすれば解決できるんでしょうか?
965デフォルトの名無しさん:2008/03/05(水) 17:26:58
Spring is here.
966デフォルトの名無しさん:2008/03/05(水) 17:28:45
>>964
xの中には複数のhogeがあるだろ?hogeのリストなんだから
どのhogeのpiyoを呼びたいんだよ?って話
全部のhogeについて呼びたいんなら、
for (list<hoge>::iterator i = x.begin(); i != x.end(); i++)
 i->piyo();
967デフォルトの名無しさん:2008/03/05(水) 19:44:33
勘違いしてました。 分かりやすくありがとうございました
968デフォルトの名無しさん:2008/03/05(水) 23:23:04
Spring has come.
969デフォルトの名無しさん:2008/03/06(木) 03:22:34
Spring to gone.
970デフォルトの名無しさん:2008/03/07(金) 08:21:13
wind the spring
971デフォルトの名無しさん:2008/03/07(金) 14:06:57
gone with the wind
972デフォルトの名無しさん:2008/03/07(金) 14:51:05
ride the wind
973デフォルトの名無しさん:2008/03/08(土) 18:20:35
cut it out
974デフォルトの名無しさん:2008/03/08(土) 20:52:30
Who are you?
975デフォルトの名無しさん:2008/03/09(日) 10:28:27
coutやcinのcって何ですか?
console?character?
976デフォルトの名無しさん:2008/03/09(日) 11:51:19
>>975
c++
977デフォルトの名無しさん:2008/03/09(日) 13:29:11
プリプロセッサフリーにいつかはなるのかな?
でもincludeできなくなるのは困るな。
assertも無くなると困るな。
978デフォルトの名無しさん:2008/03/09(日) 13:29:42
console
979デフォルトの名無しさん:2008/03/09(日) 16:02:38
the answer is blowing in the wind...
980デフォルトの名無しさん:2008/03/09(日) 16:15:09
演算子オーバーロードはネームスペーススコープでやるのとクラススコープでやるのは
何が違うんでしょうか?
981デフォルトの名無しさん:2008/03/09(日) 16:24:22
メンバ関数かどうか
982デフォルトの名無しさん:2008/03/09(日) 16:27:35
>>980
1.クラススコープでしかできない演算子がある。

2.クラススコープの場合、第一引数(this)に暗黙の変換が適用されない。
二項演算子などで引数の対称性を表現できない。

3.非クラススコープで、非public部へアクセスする場合カプセル化の度合い
を弱めることになる。
983デフォルトの名無しさん:2008/03/09(日) 16:28:49
>>975
console
984デフォルトの名無しさん:2008/03/09(日) 18:07:31
C++の入門書のお勧めは?
985デフォルトの名無しさん:2008/03/09(日) 18:11:31
個人的には本じゃなく入門サイトを巡ってみることを勧めるが・・・
986デフォルトの名無しさん:2008/03/09(日) 18:12:58
入門サイトが正しいかどうか判断できない
987デフォルトの名無しさん:2008/03/09(日) 18:19:05
一番の王道は言語仕様書
988デフォルトの名無しさん:2008/03/09(日) 18:19:52
Accelerated C++ あたりか?
989デフォルトの名無しさん:2008/03/09(日) 18:21:17
入門してからAcceleratedしようぜ。
990デフォルトの名無しさん:2008/03/09(日) 18:33:53
>>986
だから巡るんだよ
本でもサイトでも1つだけを参考にするのは良くない
991デフォルトの名無しさん:2008/03/09(日) 18:34:03
>>982
1の理由が2という理解であってますか?
またstaticなメンバやグローバル関数にできない演算子は
= () -> [] の四つであってますか?

入門書はC++Primerの英語のを読んでるけど、分厚くて萎えまくりです。
992デフォルトの名無しさん:2008/03/09(日) 19:00:38
巡っても結局判断できないと思うが
993デフォルトの名無しさん:2008/03/09(日) 19:21:03
趣旨分かってる?
質問者は入門、つまりC++を理解し始めたいのであって、
言語仕様書の日本語訳を探してるわけじゃないんだよ
994デフォルトの名無しさん:2008/03/09(日) 19:26:51
>>993
くだらないこと言ってないでサイトでも本でもお薦めを教えてやればいいのに。
995デフォルトの名無しさん:2008/03/09(日) 19:29:25
いつも思うが、まずは何でもいいから自分で探してやれよ。
後々、あれは失敗だったなと思うこともあるけどそれも経験だ。
原書含め数十冊読んだが、常に手元に置くものは自然と
決まってくる。それが自分のベストセラー。
996デフォルトの名無しさん:2008/03/09(日) 19:31:26
教えたくないということだな
997デフォルトの名無しさん:2008/03/09(日) 19:34:13
【初心者歓迎】C/C++室 Ver.50【環境依存OK】
http://pc11.2ch.net/test/read.cgi/tech/1204124499/l607
998933:2008/03/09(日) 19:35:44
>>994
だから俺は複数のサイトを自分で巡って見たほうが良いと言っているんだが・・・
むしろお薦めの本を教えてやればいいのは、巡っても意味無いと言う>>992とかだろ?
999デフォルトの名無しさん:2008/03/09(日) 19:42:43
>>984
質問するならこっちの方が良いよ、ここと違って親切な人多いし

http://pc11.2ch.net/test/read.cgi/tech/1202273631/
1000デフォルトの名無しさん:2008/03/09(日) 19:43:56
だから、巡るといい複数のサイトの候補を教えてあげればいいんだよ
質問者の趣旨を汲むならね
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。