C++相談室 part60

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。
2デフォルトの名無しさん:2008/01/11(金) 18:44:27
■基本■
[C++ FAQ]
 http://www.parashift.com/c++-faq-lite/
 http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
  Cとその仕様を比較しながらの解説なので分かりやすい。
  ***** 質問の前に必ずこの二つに目を通してください *****
[C/C++ リファレンス]
 http://www.cppreference.com/ (英語)
 http://www.cppll.jp/cppreference/ (↑の日本語訳だけど最新は反映しない)
[禿 Stroustrup]
 http://public.research.att.com/~bs/
[C++ International Standard]
 http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=38110
[JTC1/SC22/WG21 - C++]
 http://www.open-std.org/jtc1/sc22/wg21/
  ここから規格の最新(2003より新しい)ドラフトがダウンロードできる。
[JIS X3014]
 http://www.jisc.go.jp/app/pager?&RKKNP_vJISJISNO=X3014
  ISO規格の日本語訳。JIS X 3014:2003はISO/IEC 14882:2003 (E)に対応。
3デフォルトの名無しさん:2008/01/11(金) 18:44:42
4デフォルトの名無しさん:2008/01/11(金) 18:44:58
5デフォルトの名無しさん:2008/01/11(金) 18:45:19
STLつかうと一気に実行ファイルサイズが10倍に?!

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

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

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

#include <stdafx.h>
後死ね。

言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
6デフォルトの名無しさん:2008/01/11(金) 18:45:37
7デフォルトの名無しさん:2008/01/11(金) 19:00:39
復活か?
8デフォルトの名無しさん:2008/01/11(金) 19:10:02
Prototype パターンに関する質問
派生させた、インスタンスの消滅(delete)は何処でやったらいい?
基底のデスクトラクタは、Effective C++ 新訂3版、宜しく
virtualで宣言してるんだけど?
9デフォルトの名無しさん:2008/01/11(金) 19:12:26
C++ Primer 4/E 買った奴いる?
内容はどうだった?
10デフォルトの名無しさん:2008/01/11(金) 19:15:00
>>8
俺はstd::auto_ptrに突っ込んでいるが。
11デフォルトの名無しさん:2008/01/11(金) 19:53:48
>>8です
とりあえず
std::auto_ptr
boost::shared_ptr
は、なしで宜しくオナガイシマス
12デフォルトの名無しさん:2008/01/11(金) 20:02:58
同等のクラスを作れ
13デフォルトの名無しさん:2008/01/11(金) 20:14:00
>>12
kuwasiku
14デフォルトの名無しさん:2008/01/11(金) 20:18:29
おもっくそ真面目に作りたきゃ Modern C++ Design でも読めばいいが、
適当でいいなら適当なソース読め。
15デフォルトの名無しさん:2008/01/11(金) 20:20:26
>>Modern C++ Designは持ってるが、読破できん
>>適当でいいなら適当なソース読め。
どこにある?
16デフォルトの名無しさん:2008/01/11(金) 20:41:09
boostなら落としてこい。
auto_ptrならコンパイラが持ってるかも知れん。検索しろ。
開発環境書かなきゃディレクトリなんてわかるか。
17デフォルトの名無しさん:2008/01/11(金) 20:50:05
>>11
std::tr1::shared_ptrという抜け穴w
18デフォルトの名無しさん:2008/01/11(金) 20:54:22
Loki のやつを使うという手も
19デフォルトの名無しさん:2008/01/11(金) 21:08:13
>>8だが
LokiはModern C++ Designに載ってるライブラリだろうが
なもん判るか、ぼけ
ってゆうか、予想はしてたが、Prototype パターンで、派生させた、
インスタンスを消滅させるのって、やっかいなんだな
20デフォルトの名無しさん:2008/01/11(金) 21:15:18
読めと言ってる訳じゃねー
21デフォルトの名無しさん:2008/01/11(金) 21:28:03
最大50桁の数字を2つ入力して
その和と積と差を求めるプログラムを作りたいんだけど、
50桁も入力できない!!!
20桁もできない

どうすれば入力できますか?
22デフォルトの名無しさん:2008/01/11(金) 21:29:37
>>19
べつにPrototypeに限らん。
生成パターンで生成させたオブジェクトは皆同じ。
元々JavaとかC#に向いた手法だよな。
23デフォルトの名無しさん:2008/01/11(金) 21:30:31
多倍長演算でググれ
24デフォルトの名無しさん:2008/01/11(金) 21:32:05
>>21
入力を文字列として読み取り、ひと桁ずつを配列に入れる。
あとはお前が筆算をやる要領でひと桁ずつ下の桁から加算する。
10を超えたら次の桁(=次の配列)に桁上げする。

単純だけど、こんなんでも一応実現できる。
25デフォルトの名無しさん:2008/01/11(金) 21:41:12
>>21
マルチ
今宿題スレに行ってるな
26デフォルトの名無しさん:2008/01/11(金) 21:48:00
>>19
>>22
個人的な意見だが、ポインタ使って、ヒープにメモリ確保するのって
後始末が煩雑だから、嫌なんだよね、静的にインスタンスが、作れないものかな・・・

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

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

>>23
ぐぐります!!
29デフォルトの名無しさん:2008/01/11(金) 23:12:53
>>28
マルチしてるのでどっちか取り下げないか?
助けてやろうにもどっちで助ければいい?
30デフォルトの名無しさん:2008/01/11(金) 23:20:49
じゃあ向こうのスレでお願いします!!
31デフォルトの名無しさん:2008/01/11(金) 23:23:23
マルチごめんなさい(ノ_・。)
32デフォルトの名無しさん:2008/01/12(土) 11:05:00
More Effective C++ 新訂3版のテクニックという章に
class NLComponent
{
  virtual NLComponent * clone() const = 0 ; // クローンメソッド
};
基底クラスに、純仮想関数を宣言して、派生クラスでインスタンスを生成する方法が
載っているんだけど、一例で、ディスク上に保存されている、オブジェクトを
std::istream strを引数にとるコンストラクタで渡してやってるんだけど
これって、なんかおかしい気がする、理由は、コンストラクタで例外が起きたらどうなるんだ?
どう思うよモマイラ
33デフォルトの名無しさん:2008/01/12(土) 11:15:58
>>32より
32の質問は却下します、スマン
34デフォルトの名無しさん:2008/01/12(土) 17:50:36
>>33
おいおい、自分で書いておいて却下するなよ。
35デフォルトの名無しさん:2008/01/13(日) 23:53:36
VC++ 2005を使っています。
テキストファイルから文字列を読み込んでいるのですが、CStdioFileなどを使った読み込みですと、1行ずつ読み込むしかありません。
これを、1行ではなく指定の区切り文字まで読み込む、というのをやりたいのです。

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

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

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

何か標準のライブラリでこのようなものはないでしょうか? よろしくお願いします。
36デフォルトの名無しさん:2008/01/14(月) 00:14:40
1文字ずつ読み込んで、望みの区切り文字列が現れたところで止める。
37デフォルトの名無しさん:2008/01/14(月) 00:35:49
>>35
getline(basic_istreamのメンバもグローバル関数のほうも)では、
\nに代わって区切る文字を指定できる。

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

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

std::wstring s1, s2;

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

//s1 == L"今日は晴れです"
//s2 == L"明日も晴れです"
3835:2008/01/14(月) 01:58:54
>>37
どうも、ありがとうございます。それを使ってみたいと思います。
39デフォルトの名無しさん:2008/01/14(月) 21:44:28
Emacs にも Visual C++ の IntelliSense のような
入力支援機能を実現する Emacs Lisp プログラムが
用意されているのでしょうか?

単純なキーワード色づけは今も使っているのですが,
もっと詳細な情報を得たいと思っています.
40デフォルトの名無しさん:2008/01/14(月) 23:51:44
C++及びオブジェクト指向初学者です(C++入門本一読程度) 。いくつかの
クラスオブジェクト(CObjxx)を任意数包含する クラス(CTestxx)を複数生成
したいと考えています。
class CObjA {...}; // 既存クラス(修正不可)
・・・
class CObjD {...}; // 既存クラス(修正不可)
class CTestA {
private:
CObjA m_objA;
CObjB m_objB;
};
class CTestB {
private:
CObjB m_objB;
CObjC m_objC;
};
・・・
class CTestF {
private:
CObjA m_objA;
CObjC m_objC;
};
int main()
{
CTestA testA;
・・・
}
現在、このような実装で検討していますが、この方法だと各CTestxx毎に
CObjxxに対するアクセサを 用意してあげる必要があり、かつ似たような
巨大なクラスCTestxxが出来上がってしまい、 スマートな実装ではない気が
しています。。。 上記のようなケースは どのように実装するのが適切なのでしょうか。
ご教授をお願いします。
41デフォルトの名無しさん:2008/01/14(月) 23:51:44
んー、それは言語系スレじゃなくてツール系スレに行くべきかな。
42デフォルトの名無しさん:2008/01/14(月) 23:56:00
>>41>>39へのレス

>>40
抽象度が高すぎてなんともいえないな…。
CTestXXはラッパークラスなんかね?
それとも唯のコンテナか…エスパーに任せる。
43デフォルトの名無しさん:2008/01/14(月) 23:58:18
>>40
各Obj毎のアクセサクラス作って多重継承してみたら?
class CObjAAccessors {
public: objA用アクセサ;
protected: CObjA m_objA;
};
class CObjBAccessors {
public: objB用アクセサ;
protected CObjB m_objB;
};
class CObjCAccessors {
public: objC用アクセサ;
protected: CObjC m_objC;
};
class CTestA: public CObjAAccessors, public CObjBAccessors{};
class CTestB: public CObjBAccessors, public CObjCAccessors{};
...
class CTestF: public CObjAAccessors, public CObjCAccessors{};
44デフォルトの名無しさん:2008/01/15(火) 00:02:24
>>39
ある。無論標準装備ではない。
45デフォルトの名無しさん:2008/01/15(火) 00:25:29
ある基底クラスと派生クラス群があって
格派生クラス群は固有タイプのパラメータ(intやdouble[2]とか)を持っているとする

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

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

という感じ

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

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

(続く)
4740:2008/01/15(火) 00:55:05
早々のご回答ありがとうございます。

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

>>43
なるほど。この方法だとCTestxxはCObjxxの機能を有しつつ、必要な部分だけを
公開できそうです。貴重なご意見ありがとうございます。
48デフォルトの名無しさん:2008/01/15(火) 02:16:35
gccでSJISファイルのコンパイルでうまくいかないので、ご教授いただけたらと思います。

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

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

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

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

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

ここでは標準出力していますが、内部文字コードはSJISのまま解決したいと思っています。
よろしくお願いいたします。
49デフォルトの名無しさん:2008/01/15(火) 08:34:52
>>41 >>44
THX
ちょ,名前だけでもw
といってもすれ違いの気もするから Emacs スレに行きます
50デフォルトの名無しさん:2008/01/15(火) 22:27:52
>>48
--input-charsetじゃなくて-finput-charsetだった希ガス
つーかすれ違い
5148:2008/01/15(火) 23:53:54
>>50
ありがとうございます。
--input-charsetは-finput-charに展開されていたと思うので確か同じことだと思います。
GCCスレに同じ質問投げてきます。失礼しました。
52デフォルトの名無しさん:2008/01/16(水) 16:52:57
下記のようにboost::arrayで代入演算子が定義されている型Tの2次元配列を
で作りたいのですが、BOOST_PPとtemlateで一般化できないでしょうか?
自分でも考えたのですが脳みそが沸騰しそうでした。

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

const boost::array<Row, YSIZE> plane = {
Row(xx, xx, ... , xx),
...
Row(xx, xx, ... , xx)
};
5352:2008/01/16(水) 16:56:53
追記
const boost::array<Row, YSIZE> plane
は手書きで初期化します。一般化したいのはRowだけです
54デフォルトの名無しさん:2008/01/17(木) 16:57:59
教えてください
Borland社のフリーのコンパイラを使用してるのですが
#defineをmakefileでのコンパイラ時に宣言するときはどのような記述がいるのでしょうか?
55デフォルトの名無しさん:2008/01/17(木) 17:08:05
>>54
-D名前
-D名前=文字列
56デフォルトの名無しさん:2008/01/17(木) 17:10:49
>>55
無事できました、ありがとうございます
57デフォルトの名無しさん:2008/01/17(木) 17:56:37
>>54-56
ほのぼのした.
58デフォルトの名無しさん:2008/01/17(木) 23:25:38
さてさて初心者が通りますよ。
今日から勉強しようと今、Visual C++ 2008 Express Editionをインストール中。

ここまでOKです。
59デフォルトの名無しさん:2008/01/17(木) 23:27:07
>>58
帰ってよし
60デフォルトの名無しさん:2008/01/18(金) 01:44:30
>>58
お前すごいな! VC2008をインスコしたのか
おれは、コンピラーすらインスコしてないよ
コンピラーぐらい、OSにおまけで付けて欲しいよな
61デフォルトの名無しさん:2008/01/18(金) 03:00:22
最近の,NET Frameworkインストール済みなWindowsだと
C#とかVB.NETのコンピラーがおまけで付いていますよ、と。
62デフォルトの名無しさん:2008/01/18(金) 10:03:24
金毘羅ー
63デフォルトの名無しさん:2008/01/18(金) 10:21:21
emacsでc++するためのリンクを集めているのですが
http://d.hatena.ne.jp/niitsuma/20080114
他にも何か有用なサイトをご存じの方
お教えいただけると幸せです
64デフォルトの名無しさん:2008/01/18(金) 14:16:25
65デフォルトの名無しさん:2008/01/19(土) 18:29:00
C++好きですか?
66デフォルトの名無しさん:2008/01/19(土) 19:33:18
Cのスーパーセットらしい  →普通
クラスを使えると便利 →やや好き
難解な文法というか落とし穴にハマる →嫌いになる(この辺で多言語に浮気)
テンプレートがわかってくる →再び好きになる
STLに感動する →好きになる
bind1stとかvalarrayに不満がでてくる →再びちょっと嫌いになる
boostがわかってくる →また好きになる
67デフォルトの名無しさん:2008/01/19(土) 20:03:21
TMPができるようになる
 →何でもいいので何か自作のライブラリを作りたくなる

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

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

巨大なプログラムを作成中に過去に自分の書いたコードが読めなくなる
 →PCを窓から投げ捨てたくなる
68引っ越してきました:2008/01/19(土) 20:17:46
VCスレからC++の問題ということで
追い出されて来ました。

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

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

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

やりたいことはわかってもらえるとは思うのですが、
もっと楽にできるよとかもあったら教えてください。
69デフォルトの名無しさん:2008/01/19(土) 20:23:50
いろいろとおかしいなw
70デフォルトの名無しさん:2008/01/19(土) 20:24:06
Mojiretsu mojiretsu(tmp_moji);
delete[] tmp_moji;
return mojiretsu;

でどう?
71デフォルトの名無しさん:2008/01/19(土) 20:44:36
>>68
newしないでMojiretuを定義してそれをreturnすれば?
Effective C++でもnewはするなと書いてあったぞ。
7268:2008/01/19(土) 20:45:00
>>70
どうもです。
なるほど、コンストラクタを呼び出す、と。
実験の結果、ちゃんと動いています。
(まあ、もとのやつでも動いているようには
見えるのですが)
7368:2008/01/19(土) 20:46:44
>>71
どうもです。
少々時間ください。初心者のため
理解するのに時間がかかりますので。
74デフォルトの名無しさん:2008/01/19(土) 20:51:27
例外安全・・・についてはまだ触れない方がいいか
混乱しそうだし
75デフォルトの名無しさん:2008/01/19(土) 20:52:05
>>68
なんぜ+=なのに、moji1がconstなんだ?

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

これでs1 == "abcdef"にならないとおかしいだろ。
7668:2008/01/19(土) 20:55:56
訂正です。

ごめんなさい。
+=でなく、+です。
7768:2008/01/19(土) 20:58:58
>>71
やっぱりわかりません。
もう少しヒントください。

あと、Effective C++のどの辺でしょうか。
そのうち読もうと買ってはあります。
7868:2008/01/19(土) 21:00:50
>>74
とらいすろーきゃっち、でしょうか。
だいぶあとということでお願いします。
7968:2008/01/19(土) 21:07:19
>>71

どこが分からないかというと、
Mojiretuを定義するには、
(コンストラクタに)文字列(char*)を
渡す必要がありますが、その文字列自体、
strcatした後のものにしなければならず、
どうどうめぐりのようで
よく分からないのです。
勘違い、ご指摘くださいませ。
80デフォルトの名無しさん:2008/01/19(土) 21:08:26
>>77
誰がdeleteの責任持つの?って言う事。
それとEffective C++は
http://www.amazon.co.jp/Effective-%E3%80%90%E6%94%B9%E8%A8%82%E7%AC%AC2%E7%89%88%E3%80%91-
%E3%82%A2%E3%82%B9%E3%82%AD%E3%83%BC%E3%82%A2%E3%82%B8%E3%82%BD%E3%83%B3%E3%82%A6%E3
%82%A7%E3%82%B9%E3%83%AC%E3%82%A4%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%E2%80%95Ascii-Addison-programming/dp/4756118089
81デフォルトの名無しさん:2008/01/19(土) 21:09:09
deleteは関数内で済ませてしまった方がいいだろう
82デフォルトの名無しさん:2008/01/19(土) 21:12:07
Effective C++持っているなら演算子の話を是非、
と思ったらMoreのほうだった……、22。

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

そして、operator +はこうする。
Mojiretsu operator +(const Mojiretsu& lhs, const Mojiretsu& rhs)
{
  Mojiretsu tmp(lhs);
  return tmp += rhs;
}
8368:2008/01/19(土) 21:16:53
>>82
どうもです。
実はMoreも持っています。
また実験してみます。
(時間がかかります)
84デフォルトの名無しさん:2008/01/19(土) 21:22:53
std::vector使え
8568:2008/01/19(土) 22:00:52
>>82
ありがとうございました!
動きました!
+=を先に定義するというのは
頭いいですねえ。
86デフォルトの名無しさん:2008/01/19(土) 22:12:44
頭がいいっつうか、定石だな。
8768:2008/01/19(土) 22:20:59
>>86
そういうものなんですね。
>>82
「More」の22の最初のページの一番下に
「単独演算子がfriendである必要はまったくない」と
あり82でもfriendがついてませんが、friendにしないと、
lhsが"rerere"のような場合に私のではコンパイルエラーに
なったのですが、まだ何かおかしいということでしょうか。
88デフォルトの名無しさん:2008/01/19(土) 22:24:53
>>87
publicなコピーコンストラクタはあるか。
+=もメンバならやはりpublicになっている?

82のは、private/protectedなメンバに全く触っていないから
friendにする必要がないという仕掛け。
8968:2008/01/19(土) 22:32:41
>>88
たびたびありがとうございますです。
コピーコンストラクタも+=も+もその他すべての
メンバ関数はpublicになっているのですが。。。
9068:2008/01/19(土) 22:37:36
あ、もしかして、+は82そのままではなく、
privateメンバを触っていますがそのせいでしょうか。

Mojiretsu operator+(const Mojiretsu& str1, const Mojiretsu& str2) { // +演算子
    String tmp_moji(str1.s);  //←コンストラクタにはクラスの文字列部を渡してます
    tmp_moji += str2;
    return tmp_moji;
}
9168:2008/01/19(土) 22:57:13
friendがないと、
error C2804: binary 'operator +' に引数が多すぎます。
error C2333: 'Mojiretsu::operator +' : 関数宣言のエラーです。関数の本体は無視されます
っていうのも出たため、実験しましたが、
どの+でもエラーになってます。。。
friendつけている限りまったくwarningさえも出ないのですが。

すいません、時間切れです、明日の夕方、また来ます。
92デフォルトの名無しさん:2008/01/19(土) 23:19:33
>>91
来なくていいよ
もっと勉強してから来い
93デフォルトの名無しさん:2008/01/19(土) 23:26:25
>>91
迷惑です。もう荒らさないで下さい。
9468:2008/01/20(日) 00:23:56
大変おじゃまいたしました。
自己解決いたしました。
(error C2804でググって英文を読みました。
確かに読んでいる本ではコード上ちゃんと
なっていますがはっきりと言葉では
書いてないんですよねー、、、)

>>88
や、その他の方々、重ね重ねありがとうございました。
大変勉強になりました。
95デフォルトの名無しさん:2008/01/20(日) 00:48:41
>>94
とりあえず次回のためには自己解決の意味を覚えとけ。
96デフォルトの名無しさん:2008/01/20(日) 02:31:03
でもクラス定義内でfriend関数を定義できるのは盲点だったと思っている。
97デフォルトの名無しさん:2008/01/20(日) 09:50:57
>>96
最初から知っていた俺がいる。
ただ、ADLでしかlookupできないというのは盲点だったと思っている。
98デフォルトの名無しさん:2008/01/20(日) 11:39:38
http://slashdot.jp/it/07/05/24/2257258.shtml?tid=58
終わってるスキルtop10にCが入ってる
c++と区別してcなのか、それともc++込みで終わってるのか
99デフォルトの名無しさん:2008/01/20(日) 12:12:16
>>98
そいつバカですね。Cが終わってるなら、C++では重過ぎて
実装できない組み込み機器はどうなるのか?
100デフォルトの名無しさん:2008/01/20(日) 12:31:48
アセンブラはリストされてないから大丈夫じゃないか?
101デフォルトの名無しさん:2008/01/20(日) 12:59:28
古いネタの揚げ足とってどうすんだよwww
102デフォルトの名無しさん:2008/01/20(日) 18:24:19
>>98
> c++と区別してcなのか、それともc++込みで終わってるのか
スラドのくだらない雑談はいいから元の記事嫁よ
って元の記事もかなりくだらないな
103デフォルトの名無しさん:2008/01/20(日) 23:04:17
C++のコーディング方法について質問です。
皆さんは、コーディング中にコメントアウトを使うでしょうか?
以前、仲間内でコメントアウトの是非で議論になりました。
私の知人はコメントアウトを使用する派で、私は使用しない派です。
皆さんは、コメントアウトの是非についてどう思うかお聞かせください。
なお、開発はVC++6.0、2003、2005などで行っています。

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

よろしくお願いします。
104デフォルトの名無しさん:2008/01/20(日) 23:38:02
コーディングスタイルはスレ違い。

コーディングスタイルにこだわるスレ
http://pc11.2ch.net/test/read.cgi/tech/1193554741/
105デフォルトの名無しさん:2008/01/21(月) 06:53:46
(コメントがしきい値以下です。)
106デフォルトの名無しさん:2008/01/21(月) 20:38:50
107デフォルトの名無しさん:2008/01/22(火) 17:37:57
英語圏向けblogでd.hatenaみたいにシンタックスハイライトできるblogないでしょうか?
108デフォルトの名無しさん:2008/01/22(火) 17:45:39
スレタイ嫁
109デフォルトの名無しさん:2008/01/22(火) 23:33:33
C++で作ればいーじゃない。
110デフォルトの名無しさん:2008/01/23(水) 02:43:19
std::cerrやstd::wcerrの<<オペレータが例外を投げるケースは存在するのでしょうか?
これらをcatch文の中で使っても安全なのでしょうか?
111デフォルトの名無しさん:2008/01/23(水) 08:49:57
>>110
標準ができる前に既にI/Oライブラリは存在していて、後方互換性
のためデフォルトではストリームは例外を投げない仕様だと思った。
exceptionメンバー関数を使ってストリームの各種状態を例外ハンドリング
に変えることは可能。
112111:2008/01/23(水) 08:50:46
ユーザー定義型についてはoperator<<,>>で何をやるかによると思うけど。
113110:2008/01/23(水) 14:51:51
>>111
basic_ios::exceptionsの存在に初めて気付きました。
おかげですっきりいたしました。
ありがとうございます。
114デフォルトの名無しさん:2008/01/23(水) 16:24:22
C++ で new されたオブジェクト(o)とクラス(CLS)が与えられたときに、
そのオブジェクトが CLS クラスのオブジェクトか判定するには
どうすればできますか?
115デフォルトの名無しさん:2008/01/23(水) 16:28:43
>>114
typeid演算子
116デフォルトの名無しさん:2008/01/23(水) 16:34:33
クラスをCLSと表すあたり、COMのCLSIDじゃないかとエスパーしてみる。
117デフォルトの名無しさん:2008/01/23(水) 17:11:05
>>115
thx

>>116
組込みですよ。
118デフォルトの名無しさん:2008/01/23(水) 18:01:08
直接dynamic_castで済むこともあるけどな。
119デフォルトの名無しさん:2008/01/23(水) 18:30:52
ただ、dynamic_cast と typeid は意味がちゃうよね。
dynamic_cast はキャスト可能な全ての型で判定が成功するけど、
typeid は(& とトップレベルの const 以外は)厳密に型が一致しないとダメ。
どっちの方がいいというのではなくて目的ごとに使い分けることになるから、
>>114 がどっちの判定がやりたいかによるね。
120デフォルトの名無しさん:2008/01/23(水) 18:40:58
dynamic_castは多相型のポインタとリファレンスにしか適用できないし。
121デフォルトの名無しさん:2008/01/23(水) 19:05:22
そうなるとそもそも仮想関数をうまく使えば
dynamic_castも要らないだろというところまで話を広げたくなるね。
122デフォルトの名無しさん:2008/01/23(水) 19:28:59
今は typeid で分岐するのが流行りなんだぜ?
123デフォルトの名無しさん:2008/01/23(水) 19:50:25
dynamic_cast じゃなくて typeid が必要になる状況ってあんま想像つかない。
どういう時に使うんだ?
124デフォルトの名無しさん:2008/01/23(水) 21:03:45
デバッグ用途とかコードジェネレータとか
125デフォルトの名無しさん:2008/01/23(水) 22:35:54
参照への参照
int& &

この表記はC++03では認められていませんが、C++0xではint&と等価なものとして
仕様が改定されることは決定済みなのでしょうか?
126デフォルトの名無しさん:2008/01/23(水) 22:52:58
ドラフトには入ってたと思うよ
127デフォルトの名無しさん:2008/01/23(水) 22:53:45
ただし、テンプレート引数が参照な時だけだっけ?

&& を素で書くと右辺値参照だったはず。
128デフォルトの名無しさん:2008/01/23(水) 23:52:55
>>126
>>127
そうですか。テンプレートパラメータが既に参照の場合、
参照引数を渡すとT& &となりエラーとなるため、これを
回避することだけを目的としてるのかもしれないですね。
type functionを書くのも面倒なので是非改定
してもらいたいです。もしかすると今でもBoostでは便利
なものがあるかもしれませんが。

右辺値参照はC++03では認められていなくて、C++0xでは
正当になる予定ですよね?
129デフォルトの名無しさん:2008/01/24(木) 00:15:13
あれ? 離して書くと大丈夫だったかもしれん。
うろ覚えだからドラフト読んでくり。
130デフォルトの名無しさん:2008/01/24(木) 00:24:22
>>129
確認してみます。
131デフォルトの名無しさん:2008/01/24(木) 00:34:53
参照への参照なんて使うことあるの?
132デフォルトの名無しさん:2008/01/24(木) 00:47:44
>>131
テンプレートでこねこねしていると、うっかり参照への参照という型が生まれることがある。
そんなもの、現状ではコンパイルエラーだが、125に書いてある通り0xだと、
Tへの参照への参照型は、単にTへの参照型として扱われるようになる。
133デフォルトの名無しさん:2008/01/24(木) 01:00:12
&  &     -> &
&  &&   -> &
&&  &   -> &
&&  && -> &&
134デフォルトの名無しさん:2008/01/24(木) 01:01:32
>>132
thx うっかり、ってことは積極的に作るものじゃないって事でOK?
135デフォルトの名無しさん:2008/01/24(木) 01:19:02
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm#s7

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm#References%20to%20References

このあたりかな。あまり理解できなかった。
改定理由はテンプレートパラメータの問題としてだけでなく、
右辺値参照との絡みもあるみたいだ。かな?
136デフォルトの名無しさん:2008/01/24(木) 01:35:59
&&& はwell-formedなのか気になる
137デフォルトの名無しさん:2008/01/24(木) 01:39:01
ill
138デフォルトの名無しさん:2008/01/24(木) 01:58:45
>>135
template<typename T1, typename T2, typename T3>
void f(T!&& x, T2&& y, T3&& y);
例えば、こんな関数にboost::refで一部の引数だけ左辺値参照にすることができる。
そんなことできて何が嬉しいって、例えばBoost.BindやBoost.Lambdaの関数呼出。

これは& &→&というより、&& &→&の説明になっているけど。
139デフォルトの名無しさん:2008/01/24(木) 13:40:10
別に boost::ref などを使わなくても,
普通に左辺値を引数にすれば左辺値参照として bind されるのでは?
140デフォルトの名無しさん:2008/01/25(金) 01:22:36
くわしく
141デフォルトの名無しさん:2008/01/25(金) 02:32:53
以下抜粋
1. lvalues can bind to an rvalue reference.

2.
struct A {};

void h(const A&);
void h(A&&);

void g(const A&);
void g(A&&);

void f(A&& a)
{
g(a); // calls g(const A&)
h(a); // calls h(const A&)
}

Although an rvalue can bind to the "a" parameter of f(), once bound, a is now treated as an lvalue.

>>139の言うとおりのような気がする。
142デフォルトの名無しさん:2008/01/25(金) 13:02:29
そもそもboost::refをなくすための&&ですやん
143デフォルトの名無しさん:2008/01/25(金) 13:17:13
いや、&&はmove semanticsのためでしょ。
boost::refはoutパラメータとして使うためにあるんだと思ってる。
144139:2008/01/25(金) 13:52:28
以下 C++0x の話で現行の言語規格とは一切関係ないです.スレ違いですいません.

>>141
あ,いえ,自分が>>139で指摘したかったのはたとえば

template<typename T>
void f(T &&x);

があったときに, f を左辺値で呼び出すと T が左辺値参照型で specialize されて
f のパラメタの型が左辺値参照型になる,つまり

int i;
f(i);    // T = int & として f が specialization される.
        // 結果 f のパラメタの型が & && -> & の decay を受けて int & と同等になる
f(42); // T = int として f が specialization される.
        // 結果 f のパラメタの型が右辺値参照型 int && になる

ということです.これによって f の引数が非 const 左辺値でも const 左辺値でも右辺値でも
問題なく受けられるようになるということを指摘したかったんです.

で,上記の仕様 (引数が左辺値か右辺値かで
テンプレートパラメタ T が参照型かそうでないかの違いが生じる) から,
f の実装内部において f が左辺値で呼ばれたのか右辺値で呼ばれたのかの識別も可能となります.

この 右辺値参照・参照型の decay ルール・関数テンプレートにおける引数推論規則 の組み合わせで
the forwarding problem が完全に解けるというのが現在の提案の骨子だったかと思います.
145139:2008/01/25(金) 13:54:25
あと,実際には>>141さんが指摘しているように
名前が付いた右辺値参照は左辺値として扱われるので,
右辺値として渡された f の引数を f の内部で引き続き右辺値として扱うには
明示的に右辺値参照に変換してやらないといけないです.
で,このために std::forward という補助的な関数テンプレートも提案されています.

template<typename T>
T &&forward(typename identity<T>::type &&x){return x;}

template<typename T>
void f(T &&x)
{
  g(forward<T>(x)); // f が右辺値で呼ばれている場合, T が非参照型になっているので
                         // forward の戻り値型が右辺値参照型になり,右辺値として g に渡される.
                         // f が左辺値で呼ばれている場合, T が参照型になっているので
                         // forward の戻り値型が左辺値参照型になり,左辺値として g に渡される.
}
146デフォルトの名無しさん:2008/01/25(金) 15:50:00
>>143
boost::refについて、これ嘘だった。
147デフォルトの名無しさん:2008/01/25(金) 16:25:54
まったく話についてけないんだが。
何が左辺値で何が右辺値なんだかもうわけわからん
右辺値で呼ぶってどういうこと?
148デフォルトの名無しさん:2008/01/25(金) 16:44:11
template <class T>
struct identity
{
typedef T type;
};

template <class T>
inline
T&&
forward(typename identity<T>::type&& t)
{
return t;
}
149デフォルトの名無しさん:2008/01/25(金) 16:49:21
>>144
f(i); // T = int & として f が specialization される.

T が int & にdeductionされるのって、パラメータが右辺値参照
のときのみのルールですよね?
150デフォルトの名無しさん:2008/01/25(金) 16:52:33
Let us first consider the rvalue reference type, T &&, in more detail in
the context of the C++ type system. What if T is itself a reference
type? Template libraries have been known to create reference to
reference types via typedefs or type manipulations. According to the
proposed resolution to Core Defect Report 106 , ordinary references obey
the equality T cv1 & cv2 & == T cv12 &, where cv12 is the union of cv1
and cv2. A similar reasoning can be applied to collapse two rvalue
references into one: T cv1 && cv2 && == T cv12 &&.

こいう文書で出てくるcv1やcv2やcv12の数字は何を意味してるんですか?
151デフォルトの名無しさん:2008/01/25(金) 17:25:21
区別するため便宜的に番号を振っているだけ。
例えばcv1 = const, cv2 = volatileなら、
vc12 = const volatileだよという話をしたいがためのもの。
152デフォルトの名無しさん:2008/01/25(金) 18:57:19
>>151
なるほど。unionは合成の意味ですね。てっきりキーワードもunionかと
思ってしまいました。
153デフォルトの名無しさん:2008/01/25(金) 19:59:08
すいません.>>145で示した forward の定義は
正確には>>148さんの書いたとおりです.

>>147
>何が左辺値で何が右辺値なんだかもうわけわからん
戻り値の型が左辺値参照型でない関数の呼び出し構文(の結果)が右辺値で,
それ以外は全て左辺値,という理解である程度通用するかと思います.

>>149
全部把握しているわけではないので推測になりますが,恐らくそうだと思います.
後方互換性の観点から考えても,
パラメタが右辺値参照型以外の場合は従来どおりの deduction になるかと.
154デフォルトの名無しさん:2008/01/25(金) 21:19:46
システムの構造体の定義をXML形式で出力したいんだけど、上手い方法があったら教えてださい。
ある構造体は中にも構造体を保持していて、その構造体は別ファイルで定義してるとか、
ifdefやら二重に定義されてるマクロやらで手動でやろうとするともうワケワカメです



155デフォルトの名無しさん:2008/01/25(金) 21:46:14
>>153
The next step is to modify the argument deduction to retain information
about the "rvalueness" of the argument: when deducing against a template
parameter of the form A1 &&, deduce A1 as a reference type when the
argument is an lvalue, and a non-reference type otherwise. According to
our T cv1 & cv2 && == T cv12 & rule, this effectively means that the
type of the argument will be A1 & when the argument is an lvalue, and A1
&& otherwise.

どうやら右辺値参照パラメータに対する特別なdeduction ruleみたいですね。
156デフォルトの名無しさん:2008/01/25(金) 23:08:28
独自ネームスペースを持つ外部ライブラリを幾つか利用して大きなプログラムを書くようになったら

#include "hoge1.h"
……
#include "hogeN.h"
#include "mylib1.h"
……
#include "mylibN.h"
#include <lib1.h>
……
#include <libN.h>

namespace current_namespace {

using ns1::hoge1;
……
using ns1::hogeN;
……
using nsN::hoge1;
……
using nsN::hogeN;
……

な感じで各ファイルの先頭が埋め尽くされるようになりました。
皆さん、どのように解決しているのでしょうか?
157デフォルトの名無しさん:2008/01/25(金) 23:51:26
全てのヘッダを include するヘッダを作って、ソースコードの先頭で
#include "all.h"
とする。
158デフォルトの名無しさん:2008/01/25(金) 23:53:59
リコンパイルで半泣きコースだな
159デフォルトの名無しさん:2008/01/26(土) 00:11:45
リコンパイルで半泣きといえば、いろんな本で冗長インクルードガードが嫌われてるのは何でよ?
VC++2005の #pragma once を使ってる場合ですら200ファイルほどのプロジェクトでリビルド時間が半減したんだけど。
160デフォルトの名無しさん:2008/01/26(土) 00:27:07
>>157
using もヘッダん中ですんのか?
161デフォルトの名無しさん:2008/01/26(土) 00:29:14
precompiled headerになるようにしときゃいいだろ。
162デフォルトの名無しさん:2008/01/26(土) 00:48:04
>>159
よく分からんけど、

#pragma once

よりも、

#ifndef XXXXXXX
#define XXXXXXX

////

#endif

の方がビルド時間が短くなるの?
163くお:2008/01/26(土) 00:49:00
c++でエクセル用のアドインを作るやり方を教えてください。
よろしくお願いします。
164デフォルトの名無しさん:2008/01/26(土) 00:59:44
>>162
#ifndef XXXXXXX
#define XXXXXXX
#include "myhoge.h"
#endif XXXXXXX

とやって include 行を読み飛ばす方法。
myhoge.h にアクセスする必要がない、展開後のファイルサイズが小さくなる、等の理由でビルド時間が短くなることが多い。
165デフォルトの名無しさん:2008/01/26(土) 01:00:16
くおーっ!
166デフォルトの名無しさん:2008/01/26(土) 01:01:52
>>157
all.h に含まれるヘッダのどれか一つでも更新されると all.h を含むファイルが全てコンパイルされる罠。
all.h をプリコンパイルヘッダにしたところで防げません。
167デフォルトの名無しさん:2008/01/26(土) 01:08:25
批判もいいけど先に解決策を示そうぜ。
168デフォルトの名無しさん:2008/01/26(土) 01:11:42
>>164
なるほど。それだとすると、159の
>リコンパイルで半泣きといえば、いろんな本で冗長インクルードガードが嫌われてるのは何でよ?
の理由は、ヘッダファイル使用時にやることが増えるから。かな?

いや、そっちの方が早いってのなら、合理的な理由じゃないとは思うけど
多分159に対する答えは、そんなところだと思う。
169デフォルトの名無しさん:2008/01/26(土) 01:12:55
170デフォルトの名無しさん:2008/01/26(土) 01:39:56
初歩的な質問で申し訳ないのですが、ヘッダファイルの中で行う以下のような
0クリアは問題ないですか?sizeof(this)は正しく計算されます?

class HOGE
{
int a,b,c;
char str[128];

void init(void)
{
memset( this, 0, sizeof(this) );
};
};
171デフォルトの名無しさん:2008/01/26(土) 01:41:18
>>170
やってみりゃいいじゃん
172デフォルトの名無しさん:2008/01/26(土) 01:44:07
いえ、できれば構文的に正しいのか知りたいのですが…
テストのクラスで成功しても、他のクラスでは失敗するかもしれないので。
173デフォルトの名無しさん:2008/01/26(土) 02:03:15
>>172
コンパイルが通れば、構文的には正しい。
というのは置いといて、
メンバ変数をクリアしたければ、sizeof(*this)とすべき。
そして重要なのは、その方法が使えるのはPOD型だけ。
例えばHOGEに仮想関数を追加すると、動かなくなる。
174デフォルトの名無しさん:2008/01/26(土) 02:03:42
構文って意味分かってんのかいな…。
175デフォルトの名無しさん:2008/01/26(土) 03:01:40
>>173
詳しく有難うございます。納得できました。

>>174
「構文」は間違いでした。>>173のような事を表したかったのですが、
そういう場合は何と呼ぶべきですかね…
176デフォルトの名無しさん:2008/01/26(土) 03:20:13
>>175
つか、何がしたいの?
177デフォルトの名無しさん:2008/01/26(土) 04:53:51
今タイピングのアルゴリズムでゲーム中に「し」を「si」と「shi」のどちらでも受け付けるとような操作を考えています。
現段階では文字列クラスを用意して双方向リンクリストを使って分岐を操作して居るんですが、どうしてもコードが複雑になってしまいます。
もう少し簡単なアルゴリズムや便利なSTLなどがあったら教えてください。
文字列クラス
class characterData
{
private:
wchar_t ch; // 単語を構成する文字
Databace* follow; // この文字に続く文字へのポインタ
Databace* other; // 分岐文字へのポインタ
Databace* rear; // この文字の前の文字へのポインタ
public:
Databace(); Databace(wchar_t, Databace*, Databace*, Databace*, unsigned char); ~Databace();
// 変数の値を設定する関数群
void setFollow(Databace*); void setOther(Databace*); void setRear(Databace*); void setCh(wchar_t); void setLevel(unsigned char);
// 変数の値を返す関数群
wchar_t getCh() const; Databace* getFollow() const; Databace* getRear() const; Databace* getOther() const;
};
文字列を作るクラス
class createString
{
private:
Databace* end; // 文字列の最後の文字へのポインタ
Databace* div; // 分岐文字がある場合のみendと違う場所を指す
void add(const int n, ...); // n個の文字を追加する
public:
CStrManage(); ~CStrManage();
// elementをローマ字に変換しbaseの後ろに追加する
bool convert(const wchar_t* element, Databace* base);
};
178デフォルトの名無しさん:2008/01/26(土) 05:00:27
追加用の関数はこうなっています
void createString::add(const int n, ...) {
va_list args_pointer; wchar_t* arg_wchar; size_t length;
va_start(args_pointer, n);
// 文字を分岐させる
for(unsigned char i=0; i<n; i++) {
arg_wchar = va_arg(args_pointer, wchar_t*);
length = wcslen(arg_wchar);
// 分岐用文字列を作成する
Databace cdb; // ダミーの作成
Databace* tmp = &cdb; // 追加先の指定
Databace* rear = NULL; // 現在地の記憶
// 文字の追加
for(unsigned char s=0; s<length; s++) {
Databace* data = new Databace();
if(s==0) { rear = data; } // 追加前の場所を記憶
// 文字データの設定
data->setFollow(NULL); data->setOther(NULL); data->setCh(arg_wchar[s]); data->setLevel(s + 1);
if(s==0) { data->setRear(end); } // 前の文字を参照させる
else { data->setRear(rear); } // 新しく作った文字列の先頭を参照させる
// 文字を追加
tmp->setFollow(data); tmp = tmp->getFollow();
}
// 作成した文字をデータベースに追加する
if(i!=0) {
div->setOther(tmp2->getFollow()); div = tmp; // 作成した文字を追加
div->setFollow(cdb.getFollow()); div = end; // 分岐後の参照先を設定
} else { div->setFollow(cdb.getFollow()); end = div = tmp; }
}
va_end(args_pointer);
}
179デフォルトの名無しさん:2008/01/26(土) 05:34:13
>>170
sizeof(this) ってポインタのサイズだと思われ
sizeof(*this) にしないとだめなんじゃね?
180179:2008/01/26(土) 05:36:04
って、すでに173で指摘されてた・・・
181110:2008/01/26(土) 06:16:08
>>177
std::listを使って一本のリストを作って、リストの各要素のオブジェクトを工夫したほうがいいよ。
リストクラス自作するにしても、これはあまりにも酷い。
せめてコンパイルが通りそうなコードを読ませてくれ。
182デフォルトの名無しさん:2008/01/26(土) 11:09:34
>>175
そもそも、クラスの初期化を外部から行なってはいけません。
183156:2008/01/26(土) 11:23:55
結局、他の人はどうしてるの?
184デフォルトの名無しさん:2008/01/26(土) 11:48:39
折角階層的にネームスペースを宣言しているのに、ユージング宣言し捲くるってどうなのよ。
そんなばかげたことする香具師いないからレスがつかないんじゃね?
185デフォルトの名無しさん:2008/01/26(土) 11:54:16
using なんて普通は使わないよな。
186デフォルトの名無しさん:2008/01/26(土) 12:04:47
>>166
all.hにはすべてのヘッダファイルではなく、外部から提供されたライブラリのヘッダだけ入れておけば
基本的に更新することはないんじゃない? (その場合、all.hというネーミングは不適切だね。)
187デフォルトの名無しさん:2008/01/26(土) 12:05:50
目的を既に忘れてるな
188デフォルトの名無しさん:2008/01/26(土) 12:18:43
using 宣言は使うだろ。
using しないとコードが汚くなる。
そこらじゅう ns1::ns2::hoge() とか nsN::nsM::hoge() とかばかりになるぞ。
189デフォルトの名無しさん:2008/01/26(土) 12:21:44
ある程度のプロジェクトではファイルの先頭が #include や using で埋め尽くされるのは避けられないこと。
耐えろ。
190デフォルトの名無しさん:2008/01/26(土) 12:22:45
>>188
おまいはヘッダファイルでも using 使って
迷惑かけるタイプか
191デフォルトの名無しさん:2008/01/26(土) 12:26:55
>>190
どっからヘッダファイルで using なんて考えが出てきたんだ?
*.h と *.cpp では書くものが違うのはあたりまえだろうが。常考。
192デフォルトの名無しさん:2008/01/26(土) 12:32:23
using なんて使わなくても
名前空間のエイリアス作ればいいだろ。
193デフォルトの名無しさん:2008/01/26(土) 12:35:08
>>188
namespace fuga1 = hoge1::hogeA::hogeX;
namespace fuga2 = hoge2::hogeB::hogeY;
namespace fuga3 = hoge3::hogeC::hogeZ;
……
みたいな解決策もある。
194デフォルトの名無しさん:2008/01/26(土) 12:36:58
using は関数増えた時に別の関数が選択される恐れがあるから怖い。
エイリアス作ろうぜ。
195デフォルトの名無しさん:2008/01/26(土) 12:40:22
>>194
例は?
using 指令と違って using 宣言では名前が衝突するとコンパイルすら通りませんが?
196デフォルトの名無しさん:2008/01/26(土) 12:41:57
そもそもネームスペースが上手く使われてる大規模プロジェクトって見たことないな。
パッケージ名を接頭辞に持つプロジェクトの方が上手くいってたりする。
197デフォルトの名無しさん:2008/01/26(土) 12:44:54
>>195
そりゃ嘘を教えられたな。
確かにエラーになることは多いが、エラーにならない事もある。
==========
namespace Hoge { void Foo(); }
namespace HogeHoge { void Bar(); }

using Hoge::Foo;
namespace HogeHoge {
 void Bar() { Foo(); } ← Hoge::Foo
}
==========
namespace Hoge { void Foo(); }
namespace HogeHoge { void Foo(); void Bar(); }

using Hoge::Foo;
namespace HogeHoge {
 void Bar() { Foo(); } ← HogeHoge::Foo
}
198デフォルトの名無しさん:2008/01/26(土) 12:48:05
>>193 の方法でいいんじゃない?
これなら普通は namespace の数 < 識別子の数 なので先頭部分は少し短くなる。
ただし、その代わりにコードは少し長くなる。
どっちにしろ先頭が namespace で埋め尽くされるのは変わらないが。
199デフォルトの名無しさん:2008/01/26(土) 12:54:22
そだよ。エイリアスが一番マシ。

ただ、エイリアスは .cpp のグローバルでのみ作るべし。
名前空間内で作っちゃうとまたややこしい問題が生じる。
200デフォルトの名無しさん:2008/01/26(土) 12:59:57
グローバルで using してたら意味ないだろ。
namespace HogeHoge {
 using Hoge::Foo;
 void Foo();
}
で普通にエラーでたぞ。
201デフォルトの名無しさん:2008/01/26(土) 13:04:43
>>200
あらホント。
202デフォルトの名無しさん:2008/01/26(土) 13:04:57
namespace Hoge { void Foo(); }
namespace HogeHoge{
namespace Hoge { void Foo(); }
void Bar(){ Hoge::Foo(); } <- HogeHoge::Hoge::Foo
}

別に間違いようはいくらでもある。
203デフォルトの名無しさん:2008/01/26(土) 13:06:33
名前空間って厄介だよな。
204デフォルトの名無しさん:2008/01/26(土) 13:08:55
>>202
これって防ぎようなくね?
どうすんの? これ。
205デフォルトの名無しさん:2008/01/26(土) 13:11:53
>>204
::Hoge::Foo() でアクセスできるよ。

206デフォルトの名無しさん:2008/01/26(土) 13:12:27
>>205
なるほど・・・。
でも、常日頃から :: から始めないと防げないよな。
207デフォルトの名無しさん:2008/01/26(土) 13:13:53
そもそも他人の名前空間と同じ名前の名前空間を
後から作るという時点で間違いだとは思うが、
開発中に後から導入したライブラリが・・・ということもあるか・・・。
208デフォルトの名無しさん:2008/01/26(土) 13:17:40
ちなみにこんなのも。

namespace Fuga { void Foo(); }
namespace Hoge = Fuga;

namespace HogeHoge {
class Hoge { public: static void Foo(); };
void Bar(){ Hoge::Foo(); } <- HogeHoge::Hoge::Foo();
}
209デフォルトの名無しさん:2008/01/26(土) 13:22:31
名前空間はクラス名・関数名・変数名なんかと違って規約がなかったりするから、結構みんなテキトーにつけてたりする。
酷い話だとグループ全員が自分用の関数を mylibs に入れていた例が...
210デフォルトの名無しさん:2008/01/26(土) 13:25:14
幾何学ライブラリで geom が衝突したりとかだな。
211デフォルトの名無しさん:2008/01/26(土) 13:28:54
かといってJavaみたいにドメインを逆さにするのもなぁ
212デフォルトの名無しさん:2008/01/26(土) 13:32:14
>エイリアスは .cpp のグローバルでのみ作るべし。
グローバルに alias 作るとヘッダが変わったときに突然コンパイルが通らなくなることあるよ。
213デフォルトの名無しさん:2008/01/26(土) 13:35:49
前に関ったプロジェクトは常にフル指定?でメソッドを呼び出すべし

という規約があった

基底クラスのメソッドさえも
Hoge::Foo:Base:Dosomething();

多重継承を多用していたからという事情もあるんだけど

面倒だけど、安全ではある
214デフォルトの名無しさん:2008/01/26(土) 13:46:38
その面倒なのがイヤだから using を使いたい、alias を使いたいってんだと思うが。
ぐるっと一周してきた感じだな。
215デフォルトの名無しさん:2008/01/26(土) 14:07:49
グローバルにエイリアス量産するぐらいなら名前空間内で using 宣言した方がいいと思う・・・
216デフォルトの名無しさん:2008/01/26(土) 18:53:06
しかしだな、エイリアスと別の名前空間が衝突することもあってだな・・・。
217デフォルトの名無しさん:2008/01/26(土) 19:00:54
無限下降スパイラル
218177:2008/01/26(土) 19:12:06
>>181
すいません、文字列クラスがcharacterDataではなくDatabaceでした。
>std::listを使って一本のリストを作って
listやmapを使うことも考えたんですが、リスト化した後のタイプの分岐判定のアルゴリズムが思いつかず断念しました。
なのでその辺のアルゴリズムのアドバイスも出してくれると助かります。
>コンパイルが通りそうなコード
コンパイルも通って動作確認もしてあるので正常に動作しているとは思います。
ただ、これだけ乱雑になると可読性に欠けてバグの温床になりそうなのでアイディアを聞きたいと思った次第です。
219デフォルトの名無しさん:2008/01/27(日) 01:56:06
>>175
遅レスだけど、
そういう場合は鼻から悪魔がでますか?って聞けばいいよ。
220デフォルトの名無しさん:2008/01/27(日) 11:37:37
//xxx.cpp
namespace
{
namespace ns = long::longlong::longlonglong::ns;
}

void F1()
{
ns::Foo();
}

221デフォルトの名無しさん:2008/01/27(日) 13:21:55
template <typename T> //primary template
class Test {
public:
 enum { Result = 1 };
};

template <typename T> //T const に対する partial specialization
class Test<T const> {
public:
 enum { Result = 2 };
};

template<typename T>
void f(T t)
{
 cout << Test<T>::Result << endl;
}

int main()
{
 int i = 1;
 f(i); // @ --> 1が表示される

 int const j = 1;
 f(j); // A --> 1が表示される

}

222221:2008/01/27(日) 13:22:31
221です。続きです。

>>221 のtype functionについて疑問があります。
main関数内のAの呼び出しでは、渡している引数の型は確かに int const の
はずですが、結果はprimary templateが呼び出されます。Aでは T が
int const に deduction されて、T const に対する partial specialization
が呼ばれ、結果が2 になると思ったのですが、そうはなりませんでした。
明示的に f<int const>(j); とすれば 2 が表示されます。
何故 A の呼び出しで T が int const に deduction されないのでしょうか?
223221:2008/01/27(日) 13:54:47
int const val;
のように変数valを定義した場合、valの型にconstは含まれるのでしょうか?

int const& ref;
の場合は、refの型は int const& となりconstは含まれますよね?
224デフォルトの名無しさん:2008/01/27(日) 15:46:48
int const val; と const int val; は等価。
val の型に const は含まれる。
225デフォルトの名無しさん:2008/01/27(日) 15:57:41
>>222
パラメータリストのconst修飾は関数の型としては無視される、
ということからだろうと思われる
たとえばvoid f(int);とvoid f(int const)の型は全く同一になる
f<int const>(j); とすれば 2 が表示されることに保証があるのか
俺は知らない
226221:2008/01/27(日) 16:45:57
レスありがとうございます。

>>224
>int const val; と const int val; は等価。
それは知ってます。
やはり型の一部ですよね。

>>225
>たとえばvoid f(int);とvoid f(int const)の型は全く同一になる
value functionに関するそのルールは知っています。
このプログラムはvalue functionではなく、type functionなので
引数のdeductionの問題になると思います。f<int const>(j); は
明示的に型を指定しているのでpartial specializationが使用
されることは間違いないです。ただ、constが型の一部であるにも
関わらず、int const型のテンプレート引数である j を渡しても
specializationが使用されていないのが理解できません。

結果を見る限り、const修飾子が無視されてint引数として扱われてること
になりますが、これはテンプレートの標準における正しい仕様なのでしょ
うか?

VC++ 2008 と g++ v4 ともに同じ結果でした。
227デフォルトの名無しさん:2008/01/27(日) 16:49:54
そもそも const int を int な引数の関数に渡せるしね。
規格でどうか知りたいなら、規格を読むのが一番だ。
228221:2008/01/27(日) 17:09:22
>>227
それはvalue functionのパラメータ及び引数のルールであって、
テンプレートのtype parameterのdeductionはまた別の問題のよ
うに思います。もう少し規格を見てみます。
229221:2008/01/27(日) 17:12:18
>>227
>>228は撤回します。
確かにそれが理由のような気がします。
そうすると、const int と T を比べると T が intに
deductionされるのも頷けます。
230デフォルトの名無しさん:2008/01/27(日) 17:14:12
>>226
>partial specializationが使用 されることは間違いないです

ああそりゃそうか

>これはテンプレートの標準における正しい仕様なのでしょうか?

14.8.2 -3-にあった
231デフォルトの名無しさん:2008/01/27(日) 17:17:06
手元にドラフトがあるのでそれで調べてみたが、14.8.2.1 p2 にそれらしきものが。

14.8.2.1 Deducing template arguments from a function call
If A is a cv-qualified type, the top level cv-qualifiers of A's type are ignored for type deduction.
232デフォルトの名無しさん:2008/01/27(日) 17:18:11
あー、そっちかもしれん。>>230
233デフォルトの名無しさん:2008/01/27(日) 17:19:04
>>226
type function とか value function とか、何の方言?
意味がわからない。
234デフォルトの名無しさん:2008/01/27(日) 17:20:09
最新のドラフトを見ると怖いことが書いてあった

[ Note: f<int>(1) and f<const int>(1) call distinct functions even though both of the functions called have the
same function type. .end note ]
235デフォルトの名無しさん:2008/01/27(日) 17:24:04
>>234
まあ明示的に指定する分には違っててもいいんじゃね?
236221:2008/01/27(日) 17:34:09
>>230
>>231
>>232
>>233
>>234
>>235
みなさんレスありがとうございます。

>>231
まさにそれかと思います。同じことがJosuttisのC++ Templateにも
書いてありました。

こういう事情のようでです。

template<typename T> void f(T);
template<typename T> void g(T&);

int const ci = 123;

f(ci); // T is int
g(ci); // T is int const

すっきりしました。
237デフォルトの名無しさん:2008/01/27(日) 17:40:02
int const& の const はトップレベルの const じゃないからそうなるわな。なるほど。
238221:2008/01/27(日) 17:47:45
>>233
詳しいことは知りませんが、
現段階で標準で規定された言葉ではないと思います。
テンプレートの本に書かれていました。
value functionはいわゆる通常の関数を指します。
パラメータがtype、引数が値。
type functionとは、通常クラステンプレートで
実現されるものらしいです。
パラメータがテンプレートパラメータ、引数がtype。

struct Widget{};
Test<Widget>::Result;

>>221のTestクラステンプレートの場合、Widgetが引数で
type functionの戻り値がTest<Widget>::Resultと考え
ると通常の関数のように関数とみなせるというもだと
理解してます。
239デフォルトの名無しさん:2008/01/27(日) 18:03:50
>>238
「テンプレートの本」ってどれだ?

普通に「関数」と「クラステンプレート」って言ったほうがいいと思うよ。
意味の違いを正しく表している呼び名だとは思えないからね。
後者は「(テンプレート)メタ関数」とか呼ばれるもののような気もするなぁ。
240221:2008/01/27(日) 18:36:02
>>239
ここでいうtype functionとは
最近の言葉で表せばメタ関数でしょうね。
Boost::mplなどの最近のメタプログラミングで
使われていますが。

本はC++ Template The Complete Guideです。
著者は標準化委員会の現メンバーでもあり
信用できないものではないと思います。

通常の関数と対比して、コンパイル時に型を引数
とする”関数”という概念的に上手い言葉だと感じ
ているので自分はなるほどと思いました。
241デフォルトの名無しさん:2008/01/27(日) 19:21:38
>>240
メタ関数でいいならそう言ったほうがいいでしょ。
わざわざ廃れた用語を使い続ける理由もない。
242デフォルトの名無しさん:2008/01/27(日) 19:32:18
meta function == type function
別に正式な名前じゃないけど、
type functionってのはそこそこみる表現だから覚えておいてもいいと思うよ
243デフォルトの名無しさん:2008/01/27(日) 23:07:12
>>241
別に廃れてるわけではないよ。
概念を表した言葉だから。
244デフォルトの名無しさん:2008/01/29(火) 11:46:24
適当なオブジェクトのポインタが与えられたとき、そのオブジェクトのクラスがある特定の
名前と引数のタイプを持ったメンバ関数を持つときに限りその関数を呼んで処理したい
のですが、C++ で可能でしょうか?

あ、オブジェクトは必ずしも共通のスーパークラスを持たないとします。要はそういう
場合でも仮想関数的なことをしたいというか...
その特定のメソッドをもつ別クラスを作って、それを全てのオブジェクトで多重継承、
というのも考えているのですが、ちょっとダサいかな? と思って。あとソースのないクラス
では無理ですよね(今のところはソースのあるクラスだけでいいんですが)。

そもそもこんなことを考える事自体ナンセンス、と言われるとアレなんですがw
245デフォルトの名無しさん:2008/01/29(火) 12:35:21
ポインタの型がテンプレート引数で与えられているならば、可能
246デフォルトの名無しさん:2008/01/29(火) 12:41:29
>>245 嘘だろ。怪しいからソースを晒してください。
247デフォルトの名無しさん:2008/01/29(火) 12:44:38
>>244おとなしく多重継承すべし。
248デフォルトの名無しさん:2008/01/29(火) 12:52:14
>245が言いたいのは「コンパイル時にクラスが確定できる」場合だろ。
249245:2008/01/29(火) 13:41:34
おかしいな。VC9だとhas_xxxが通らない。
自分で書いてみても、やはり通らない。
こんな風にSFINAEを使ってやればできるはずなんだけど。

struct BjarneStroustrup
{ void hage() ; } ;
struct Others
{ void fusafusa() ; } ;

template < typename T >
struct has_hage
{
  struct Yes { char a[1] ; } ;
  struct No { char a[2] ; } ;

  template < typename Y > static Yes test(typename Y::hage const *) ;
  template < typename Y > static No test(...) ;

  static bool const value = ( sizeof( test<T>(0) ) == 1 ) ;
} ;

BOOST_STATIC_ASSERT(( has_hage<BjarneStroustrup>::value )) ;
BOOST_STATIC_ASSERT(( has_hage<Others>::value )) ;
250245:2008/01/29(火) 13:42:58
最後の一行間違ってるけど気にしないで
251デフォルトの名無しさん:2008/01/29(火) 14:42:17
template < typename Y > static Yes test(typename Y::hage const *) ;

はおかしくないか?
マッチしなかったぞ。

やるなら

template < typename Y > static Yes test(void (Y::*)(void));

か?

でも、これじゃあ関数名の一致の評価はムリだな。
何か仕組みが必要か。
252デフォルトの名無しさん:2008/01/29(火) 14:42:50
struct BjarneStroustrup
{
void hage(){cout << "hage" << endl; }
};
struct Others
{
void fusafusa(){cout << "fusafusa" << endl;}
};
253デフォルトの名無しさん:2008/01/29(火) 14:43:13
template <typename T>
struct has_hage
{
typedef char One;
typedef struct { char a[2]; } Two;

template < typename Y > static One test(void (Y::*)(void));
template < typename Y > static Two test(...);

enum { value = sizeof(test<T>(0)) == 1 };
} ;

template <typename T>
void func(T)
{
cout << "too bad" << endl;
}

template <>
void func(BjarneStroustrup* p)
{
p->hage();
}

template <typename T>
void call(T* t)
{
if(has_hage<T>::value)
func(t);
}
254デフォルトの名無しさん:2008/01/29(火) 14:44:52
int main()
{
BjarneStroustrup b;
call(&b);

Others o;
call(&o);
}
255デフォルトの名無しさん:2008/01/29(火) 15:02:09
struct BjarneStroustrup
{
typedef void HAGE;
void hage() const {cout << "hage" << endl; }
};

こういう風に typedef 定義して(擬似的な名前一致)

template < typename Y > static One test(typename Y::HAGE *);

じゃだめかいな。
256デフォルトの名無しさん:2008/01/29(火) 15:34:33
これじゃあシグニチャが合わないか。
257デフォルトの名無しさん:2008/01/29(火) 15:45:03
ちょっと変更

struct HAGE{};

struct BjarneStroustrup
{
template <typename T>
void hage();
template <>
void hage<HAGE>() {cout << "hage" << endl; }
};

template <typename T>
struct has_hage
{
・・・・・
template < typename Y > static Two test(...);
・・・・・
} ;

template <>
void func(BjarneStroustrup* p)
{
p->hage<HAGE>();
}
258デフォルトの名無しさん:2008/01/29(火) 15:46:00
こっちだった。

template <typename T>
struct has_hage
{
・・・・
template < typename Y > static One test(void (Y::*)(HAGE));
・・・・
} ;
259デフォルトの名無しさん:2008/01/29(火) 17:12:00
このスレって頭悪い奴多いね
260デフォルトの名無しさん:2008/01/29(火) 17:20:47
そもそもプログラミングしてる時点でアレだしな
261デフォルトの名無しさん:2008/01/29(火) 17:55:27
ググったらこんなのが出てきた。
http://www.gamedev.net/community/forums/topic.asp?topic_id=435173
これを基に少し改造してみた。BjarneStroustrupとOthersは>>249の定義を使用。
#include <iostream>
#include <boost/mpl/bool.hpp>
//#include <boost/type_traits.hpp>
struct SFINAE {
    typedef char one;
    typedef struct { char c[2]; } two;
};
template<typename T>
class has_hage_impl {
    template<void (T::*)()> struct Wrap {};
    template<typename U>
    static SFINAE::one Determine(Wrap<&U::Hage>* w);
    template<typename U>
    static SFINAE::two Determine(...);
public:
    static const bool value = sizeof(Determine<T>(0)) == sizeof(SFINAE::one);
};
template<typename T>
struct has_hage : boost::mpl::bool_<has_hage_impl<T>::value> {};
//boost::integral_constant<bool, has_hage_impl<T>::value>も可
int main() {
    std::cout << std::boolalpha
        << has_hage<BjarneStroustrup>::value << '\n'
        << has_hage<Others>::value << std::endl;
}
262デフォルトの名無しさん:2008/01/29(火) 18:26:26
>>259
ほんとだね
263デフォルトの名無しさん:2008/01/29(火) 18:27:59
>>259
具体的な解決策はありますか?
264デフォルトの名無しさん:2008/01/29(火) 18:31:49
クラステンプレートのテンプレイート引数をバインドしたいと思っています。
考えたのは

template <class T1, class T2>
class A {...};

template <class T1>
class AInt {
public:
  typedef A<T1, int> type;
};

このような方法ですが、AInt<Hoge>::typeとしないといけないところに不満が残ります。

typedef A<T1, int> template <class T1> AInt;
こんな感じで完全にバインドしてしまう方法はないでしょうか?
265デフォルトの名無しさん:2008/01/29(火) 18:33:14
0,1,2,3,4
から
2個取り出すときの全組み合わせ
3個
4個
5個(は1通りだけど)
を文字列(stringでもcharでも)として吐き出すプログラムを
書きたいんですがアイディアだけでもいただけないでしょうか?
266デフォルトの名無しさん:2008/01/29(火) 18:41:20
>>265
それなんて宿題?
267デフォルトの名無しさん:2008/01/29(火) 18:44:37
>>264
今のC++にはない。0xに乞うご期待。

その方法が嫌なら、使える場合が限られるけど継承するか、
template <class T1>
class AInt : public A<T1, int> {};
あとはプリプロセッサマクロで何とかするか。
268デフォルトの名無しさん:2008/01/29(火) 18:47:21
や、宿題じゃないんですが自分でプログラムかいててハタと迷ったので・・
スレチならすいません
269デフォルトの名無しさん:2008/01/29(火) 19:03:09
>>265
なにが固定でなにが引数になるか書いてくれないと答えようがないぜ。
270264:2008/01/29(火) 19:03:55
>>267
そうなんですか。
ありがとうございました。
271268:2008/01/29(火) 19:03:59
すいませんネットから拾ったプログラムを改変したら多分出来ました。

#include <stdio.h>
int main(int argc ,char *argv[]){
int a=0,b=0,c=0,d=0;
for (a=0;a<=4;a++){
for (b=0;b<=4;b++){if(b==a || a>b)continue;
for (c=0;c<=4;c++){if(c==a || c==b || b > c)continue;
for (d=0;d<=4;d++){ if(d==a||d==b||d==c||c>d)continue;
cout <<a<<b<<c<<endl;
}
}

}
}
return 0;
}
272デフォルトの名無しさん:2008/01/29(火) 19:06:23
スレ違いだな。
ここは見ての通り、C++の規格書を暗記している奴が、
C++の文法で、Bjarne Stroustrupがハゲているかどうか、
コンパイル時に判定するスレだ。
ソースコードが実用的かどうかは、どうでもいい奴らなんだよ。
重要なのは規格違反かどうかということだけだ。

まあ、大方のスレ住人もハゲてるんだけどな。

273デフォルトの名無しさん:2008/01/29(火) 19:07:30
ゆとり教育のカリキュラムには順列・組み合わせとかないの?
274268:2008/01/29(火) 19:08:50
>272
thx
俺はケツ毛までフッサフサです。
275デフォルトの名無しさん:2008/01/29(火) 19:20:28
276デフォルトの名無しさん:2008/01/29(火) 19:43:27
>>244
テンプレートじゃ無理なんか?
277245:2008/01/29(火) 20:05:40
>>261
お、それだとVC9でもBOOST_STATIC_ASSERTが通った。
でもおかしいな、確か昔、C++ Templatesで読んで、実際に自分で試してみて、
スゲーと感動した記憶があるんだけど。
たしかVC7だったかな。

あとBoostのhas_xxxって、これ関数じゃないんだね。知らなかった。
278デフォルトの名無しさん:2008/01/29(火) 20:17:41
VC++6.0で開発してます。
CHttpFile::SendRequestEx() にて、
CInternetException以外の例外が発生するケースが稀にあるようなんですが、原因が特定できず悩んでいます。

そもそもCInternetException* の例外以外がスローされることってあるんでしょうか?
どっかのサイトでは、CFileExceptionもスローされると書いてあったんですが・・・。

どなたか、このような経験が方いらっしゃいましたら御教授下さい。
279デフォルトの名無しさん:2008/01/29(火) 20:20:17
スレ違い。
280デフォルトの名無しさん:2008/01/29(火) 20:24:40
>>277
で、結局、>>244 のやりたいことは可能なのか?
281デフォルトの名無しさん:2008/01/29(火) 20:26:51
オナニーレスばっかりだな
282デフォルトの名無しさん:2008/01/29(火) 20:32:21
しこしこ
283デフォルトの名無しさん:2008/01/29(火) 20:35:25
ズルムケ
284デフォルトの名無しさん:2008/01/29(火) 20:35:45
それは鈴木ムネオの秘書だろ
285デフォルトの名無しさん:2008/01/29(火) 20:46:26
>>280
さー?
>>244が静的な多様性でいいのかどうか分からないからなんとも。
しかし動的な多様性がほしいとすると、引っかかることも。
「ポインタで与えられる」、しかし共通のベースクラスがあるわけではないってことは、void *型で渡すんだろうか。
それだと特定のメンバ関数云々よりも、そもそもオブジェクトのクラスの型は何だってことになるし。

動的な多様性がほしい、
しかし、既存のコードはいじりたくないので、共通のベースクラスに純粋仮想関数は使えないというのなら、
例えばBoost.Anyに使われているType Erasureのテクニックが使えるかもしれない。
あの単純すぎるテクニックを使えば、かなり変態的なことができる。
286デフォルトの名無しさん:2008/01/29(火) 20:51:54
>>285
変態ということはわかった
287デフォルトの名無しさん:2008/01/29(火) 22:36:43
あるクラスを継承しているクラス群のみを対象にメモリ割り当てをカスタマイズしたいです
class Base{}
class Derived1 : public Base{}
class Derived2 : public Base{}
そこでこれらクラス群の内、最も大きいサイズのクラスを基準に配列を静的に用意、
Base、Derived1、Derived2をnewする時に使いたいと思ってます

struct AllocUnit{ char[???] buf;} ←ここのバッファのサイズを静的に求めたい
static AllocUnit[MAX_UNIT] memory; //sizeof(AllocUnit)*MAX_UNIT分のバッファを静的に確保
???の部分を求める方法がわかりません
MPLを使えばできそうな感じなんですが・・・

言い換えると、任意の数のクラスの内、サイズが最大のものをコンパイル時に取得する方法はないか?
という事です↓こんなイメージ
char[max_size<Base,derived1,derived2>] buf;
288デフォルトの名無しさん:2008/01/29(火) 22:49:25
>>264
俺はそういう時、
template <class T1, class T2>
class A { ... public: typedef A<T1, T2> this_t; };
として、バインドするクラスは
template<class T1>
class AInt : public typedef A<T1, int>{};
のようにpublicで継承する。

そしてクラスを記述する時はどんなものにしろ必ず
A::this_t;
AInt::this_t;
と最後に::this_tとつける気持ち悪い習慣を身に着けている。

もしくは、 #define hogehoge(class) class::this_t のようなマクロを使うとか、いろいろ手はあるけど
結局どれもいたちごっこかうへへへへへへへへへh
289デフォルトの名無しさん:2008/01/29(火) 22:55:38
>>287
こんなのでどう
template <typename A, typename B> struct max_size { enum{ value = sizeof(A) > sizeof(B) ? sizeof(A) : sizeof(B) }; };
template <typename A, typename B> struct max_size_chain { enum{ value = A::value > sizeof(B) ? A::value : sizeof(B) }; };
template <typename A, typename B, typename C> struct max_size3: max_size_chain<max_size<A, B>, C>{};
template <typename A, typename B, typename C, typename D> struct max_size4: max_size_chain<max_size3<A, B, C>, D>{};
template <typename A, typename B, typename C, typename D, typename E> struct max_size5: max_size_chain<max_size4<A, B, C, D>, E>{};

char buf[max_size5<char, int, short, long, void*>::value];
290デフォルトの名無しさん:2008/01/29(火) 22:57:36
boost mpl if_cとかとsizeof使えばいい
291デフォルトの名無しさん:2008/01/29(火) 22:57:48
template <size_t x, size_t y> struct size_t_max {
static const size_t value = x > y ? x : y;
}
struct AllocUnit {
static const size_t size = size_t_max<sizeof Derived1, sizeof Derived2>::value;
char buf[size];
}

基底クラスより派生クラスの方がサイズ大きいの分かってるから
2つの比較だけでいいべ。
292デフォルトの名無しさん:2008/01/29(火) 22:58:38
ミスって途中送信してる・・・。
こっちが本物。

#include <iostream>

struct Base { int x; };
struct Derived1 : public Base { int n; };
struct Derived2 : public Base { int n, m; };

template <size_t x, size_t y> struct size_t_max {
static const size_t value = x > y ? x : y;
};
struct AllocUnit {
static const size_t size = size_t_max<sizeof (Derived1), sizeof (Derived2)>::value;
char buf[size];
};

int main(){
std::cout << AllocUnit::size << std::endl;
}

基底クラスより派生クラスの方がサイズ大きいの分かってるから
2つの比較だけでいいべ。
293244:2008/01/29(火) 23:09:34
皆さんどうもありがとうございます。
なるほど、テンプレートの特殊化を利用って感じですか? こんな風に使えるんですね。

が、しかし、
>>285
>「ポインタで与えられる」、しかし共通のベースクラスがあるわけではないってことは、void *型で渡すんだろうか。

ビンゴでございます。テンプレートの場合変数の型で挙動が変化してるわけですよね。
自分は Objective-C も使うことがあるので今回のような疑問を持ったのですが。

>しかし、既存のコードはいじりたくないので、共通のベースクラスに純粋仮想関数は使えないというのなら、

とりあえず多重継承で共通のベースクラスを足すことをを検討しています。

>例えばBoost.Anyに使われているType Erasureのテクニックが使えるかもしれない。

そうですか、参照してみます。
294244:2008/01/29(火) 23:15:51
あ、あれ、でもvoid *で渡さなくてもいいかな? ちょっと考えてみます。
でもやっぱ多重継承の方が自然かなあ。
295287:2008/01/29(火) 23:16:19
>>289
ありがとうございます。参考にします
>>292
なるほど。確かにsizeof(Base)<=sizeof(Derived)ですもんね

よく考えたらgreater<T1,T2>的なモノを用意して、それを連ねていくだけでよかったんですね

しかし派生クラスの数が増えるたびにmax_sizeの引数増加版を定義するのが面倒・・
可変引数のtemplateがあればなぁ・・・
296デフォルトの名無しさん:2008/01/29(火) 23:20:40
>>287
template<typename T1, typename T2, typename T3>
struct MaxSize {
typedef typename if_c<(sizeof(T1) > sizeof(T2)),
typename if_c<(sizeof(T1) > sizeof(T3)),T1, typename if_c<(sizeof(T2) > sizeof(T3)),T2,T3>::type>::type,
typename if_c<(sizeof(T2) > sizeof(T3)), T2, T3>::type >::type SizeT;
static const size_t sz = sizeof(SizeT);
};
297デフォルトの名無しさん:2008/01/29(火) 23:27:59
マクロをゴニョゴニョすれば
DEFINE_MAX_SIZE(3, 100);
で max_size3〜max_size100 まで定義、みたいなこともできそうだが、
実用的には生成プログラム書いた方が楽だと思う。
298デフォルトの名無しさん:2008/01/30(水) 14:46:54
C++で継続(continuation)、あるいはそれっぽいことができるライブラリや、
C++で継続に関するページがあれば教えてください。
299デフォルトの名無しさん:2008/01/30(水) 15:44:42
まずお前の継続に関する経験について聞こうか?

全くC/C++以外の経験が無いとかいうレベルだとかなり大変だぞ。
300デフォルトの名無しさん:2008/01/30(水) 16:21:20
>>299
rubyでcallccを知り、その関連ページで勉強した程度しか知識がありません。
やりたいことは、まさにrubyのcallccで実行できるようなことです。
301デフォルトの名無しさん:2008/01/30(水) 16:34:55
「なんでも継続」は読んだ?
(Cの)setjmp/longjmpは理解してる?
302298:2008/01/30(水) 16:40:15
>>301
「なんでも継続」のページ、良さそうですね。
まずここから始めてみます。
setjmp/longjmpは、Unix C上がりなので知ってます。使った記憶は1回しかありませんが…。
303デフォルトの名無しさん:2008/01/30(水) 18:00:53
>>298
Boost.Coroutine
Hamigaki C++ Libraries
304デフォルトの名無しさん:2008/01/31(木) 00:14:39
Hamigakiってなんかのギャグかと思って調べたらほんとにあるんだな…。
305デフォルトの名無しさん:2008/01/31(木) 00:17:48
なんか最近はスーパーマリオみたいなのつくってなかったっけ
306デフォルトの名無しさん:2008/01/31(木) 07:01:14
BoostにLokiのタイプリストみたいなものってありありますか?
307デフォルトの名無しさん:2008/01/31(木) 08:16:40
cons list?
308デフォルトの名無しさん:2008/01/31(木) 14:59:51
>>306
Boost.MPLのmpl::vector等
309デフォルトの名無しさん:2008/01/31(木) 18:29:56
>>308
は?
310デフォルトの名無しさん:2008/01/31(木) 21:06:00
>>309
へ?
311デフォルトの名無しさん:2008/01/31(木) 21:18:01
>>310
ん?
312デフォルトの名無しさん:2008/01/31(木) 22:17:13
>>311
え?
313デフォルトの名無しさん:2008/01/31(木) 22:18:19
>>312
ろ?
314デフォルトの名無しさん:2008/02/01(金) 00:43:26
>>313
す?
315デフォルトの名無しさん:2008/02/01(金) 00:49:58
>>314
け?
316デフォルトの名無しさん:2008/02/01(金) 01:17:15
やめんか
317デフォルトの名無しさん:2008/02/01(金) 05:30:19
C++的に配列はどんなものでも<vector>ライブラリを使うべきなんでしょうか?
318デフォルトの名無しさん:2008/02/01(金) 05:43:56
>>317
そんなことはないけど、 ruby や python みたいな言語を触ってる人から見て
配列といって当てはまるのは std::vector でしょうね。組み込みの配列はいろいろ
歴史的な問題も残ったままだし。
319デフォルトの名無しさん:2008/02/01(金) 07:29:58
>>317
サイズが完全に決まってるなら
巨大でさえなければ、
組み込みの配列を使った方が効率がいい。
320デフォルトの名無しさん:2008/02/01(金) 07:53:11
tr1::array早く来い来い。
321デフォルトの名無しさん:2008/02/01(金) 12:08:03
普通の配列ならスタックに蓄えられるとか、newすればヒープから領域を取ってくるとか、
配列を扱うならそこら辺の知識もあってほしいな。
322デフォルトの名無しさん:2008/02/01(金) 14:50:07
alloca()
323デフォルトの名無しさん:2008/02/01(金) 21:09:38
まぁ、スタックに蓄えられるとか、newすればヒープから領域を取ってくるとか
規格には書いてないけどな
324デフォルトの名無しさん:2008/02/01(金) 21:12:53
new はフリーストアから領域を取ってくるんです!
325デフォルトの名無しさん:2008/02/01(金) 21:18:22
mallocはヒープから領域を取ってくるんです!
326デフォルトの名無しさん:2008/02/02(土) 02:37:39
stroustrupはどこから毛を取ってくるんです!?
327デフォルトの名無しさん:2008/02/02(土) 03:14:27
>>326
お前らがnewするたび、stroustrupから領域を割り当てられているのに
ちゃんとdeleteしない奴が多いから…。
そろそろstd::bad_allocが飛んでくるぞ。
328デフォルトの名無しさん:2008/02/02(土) 12:39:36
stroustrup「virtual hair hair() = 0 はただのインタフェース!
       実際のインスタンスはもっとふさふさなの!
       バヤには見えないんだよーだバーヤバーヤ!」
329デフォルトの名無しさん:2008/02/02(土) 13:50:24
散々ネタに去れてるのにstroustrupのAAってなんでないんだろう。
俺が作ってやる。
330デフォルトの名無しさん:2008/02/02(土) 21:17:56
331デフォルトの名無しさん:2008/02/04(月) 12:00:17
毛量保存の法則
頭髪の少い場合、顎髭や胸毛、ギャランドゥなどで補い、最終的な毛量は一定
332デフォルトの名無しさん:2008/02/04(月) 12:15:26
ハゲで体毛も薄い人間は
代わりに心臓に毛が生えまくってるとか
333デフォルトの名無しさん:2008/02/06(水) 04:31:06
http://www.research.att.com/~bs/bs_faq2.html#delete-zero
> C++ explicitly allows an implementation of delete to zero out an lvalue operand

これ訳すと
「C++ は delete の実装が左辺値である対象をゼロにすることを明示的に許している」
ってことだよね?

int* p = new int;
delete p;

delete した時点で p == 0 になるような実装もアリってこと?
規格見てもそんなことしていいなんて記述は見当たらなかった。
それとも、ただの読み違い?
334デフォルトの名無しさん:2008/02/06(水) 06:32:38
そうだよ。
auto_ptrあたりなんかはそれを頼りに実装してる
335デフォルトの名無しさん:2008/02/06(水) 07:40:08
食い違ってるような
336デフォルトの名無しさん:2008/02/06(水) 07:52:37
許しているだけなのにそれを頼りにしちゃいかんのでは。
337デフォルトの名無しさん:2008/02/06(水) 08:26:25
便利のようでそうでもないかな。変な副作用はなさそうだから気にしないでおこう。
338デフォルトの名無しさん:2008/02/06(水) 14:36:13
cmake( crossplatform make) 使ってる人ってあんまりいないんですか?
みんな普通にMakefile直接書いてるの?
Windows 上にVirtual Machineでlinuxいれてlinuxとwindowsいったりきたりして開発が
以外と便利と思ったのだけど
339デフォルトの名無しさん:2008/02/06(水) 17:58:16
Makefileを作ってくれるツールがあったような気がするが、誰か名前教えて
340デフォルトの名無しさん:2008/02/06(水) 18:42:18
automake
341デフォルトの名無しさん:2008/02/07(木) 07:38:54
void Register(T* p); // newされたばかりの所有権フリーのポインタを受け取りたい
boost::scoped_ptr<T> ptr(new T);
Register(ptr.get()); // セマンティックエラーだがコンパイルは通ってしまう

この問題を解決するために、Registerの引数をshared_ptrにしていたのですが、
ポインタを共有するわけではないのに、shared_ptrはオーバースペックではないかと気になりました。
うまい方法はないですか?
342デフォルトの名無しさん:2008/02/07(木) 10:10:35
>>341
要するに Register 関数に所有権を移動させたいのよね? なら
  void Register(std::auto_ptr<T> p);
にすれば解決するような気がする
343341:2008/02/07(木) 10:43:54
>>342
レスthx。
Register(std::auto_ptr<T>(new T));
という書き方ができないのは諦めるしかないですかね。
344デフォルトの名無しさん:2008/02/07(木) 10:47:24
>>343
そういう書き方は普通にできるよ?
# もちろん T が何か具体的な型になっているとして
345341:2008/02/07(木) 12:25:13
>>344
あれ?確かにコンパイルできますね(VC2008EEで確認)。
auto_ptrのコピーコンストラクタと代入演算子の引数が非const参照なので、
一時オブジェクトは渡せないと思っていました。

http://ml.tietew.jp/cppll/cppll/article/4745
ここにもありますが、なぜなんでしょう?(vcpp 00059148って何?)
346デフォルトの名無しさん:2008/02/07(木) 12:40:28
std::auto_ptr<T> func() ;

void f()
{ std::auto_ptr<T> p = func() ; }

こんなこともできるだよ。
別のクラスをひとつ中継させてるだよ。
347デフォルトの名無しさん:2008/02/07(木) 12:41:26
コピーコンストラクタが非constなのは当たり前でしょ。
コンストラクタなんだから。
348デフォルトの名無しさん:2008/02/07(木) 13:18:22
非constな参照引数に一時オブジェクトは渡すのは規格ではダメだよね。
auto_ptrのコピーコンストラクタって非constな参照を受け取るよね。
ということは

void Register(std::auto_ptr<T> p);
Register(std::auto_ptr<T>(new T));

みたいな書き方はダメなんじゃないか?
349341:2008/02/07(木) 13:30:47
>>346
ああ、戻り値も一時オブジェクトでしたね。
そう思うと一時オブジェクトがコピーできるように作ってあって当然に感じます。
auto_ptr_refというクラスで解決してるわけですね。
>>347
よく読んでください><

どうもありがとうございました。
350デフォルトの名無しさん:2008/02/07(木) 14:11:18
>>349
そうだね。
実際、一時オブジェクトから生成するときは
通常のコピーコンストラクタは使われないね。
auto_ptr_ref経由で変換→変換で
最終的には
auto_ptr(auto_ptr_ref<T> rhs) throw()
: ap(rhs.yp) {
}
というコンストラクタで生成される。
351デフォルトの名無しさん:2008/02/07(木) 19:05:23
char *ptr = (char*)new int[0xFF];
delete[] ptr;
実際に delete[] する型は違いますが、確保したメモリは全て開放されますか?
352デフォルトの名無しさん:2008/02/07(木) 19:19:37
>>351
>In the second alternative (delete array)
>if the dynamic type of the object to be deleted differs from its static type,
>the behavior is undefined.

ってことだから、未定義動作じゃないかね
353デフォルトの名無しさん:2008/02/07(木) 19:19:45
未定義動作だろ
354デフォルトの名無しさん:2008/02/07(木) 21:36:48
すまん、誤爆しちゃったんだが元々こっちに書くつもりだったんで聞きたい。
http://pc11.2ch.net/test/read.cgi/tech/1202141921/128

//------------------------------------//
メモリが解放されてるかどうか確認する方法ってなんかあるかな?

void a( void* p ) {
if( rand() %2 ) delete p;
}

void main () {
char*pc = new char[100];
a(pc);
// pcが解放されてなかったら解放
if( soreppoino( pc ) ) delete pc;
}

みたいな。
//------------------------------------//

まぁ普通はしねーけど、MFC使ってるアプリがDRV_CLOSE送る前に
メモリ解放しちゃうっぽいから判定しなきゃいかんくなってさ。
結局はアプリ終了中か否かで判定したんだけど、まあそれはいいんだ。

聞きたいのはこういうのってあるかな?ってこと。やっぱないかな?
でもそうなるとVC6のメモリウィンドウの「??」ってどう判定してんのかが分からん。
誰かここら辺知ってる人いたらおせーてくだせい。
355デフォルトの名無しさん:2008/02/07(木) 21:55:13
標準には無い。
環境依存ならスレ違い。
356デフォルトの名無しさん:2008/02/07(木) 22:09:10
MFCに解放されないようなメモリ確保の手段を使えばいい。
357デフォルトの名無しさん:2008/02/07(木) 23:04:01
>>354
向こうの133に的確な答えが書いてあるじゃないか。そういうことができるクラスを作ればいいんだよ。
358デフォルトの名無しさん:2008/02/07(木) 23:44:53
なんかもの凄く間違った方向に突っ走ってるような。
359デフォルトの名無しさん:2008/02/08(金) 13:49:21
コンストラクタ内で、thisポインタを他のクラスに渡すことについて質問です。

コンストラクタは、オブジェクトを安全に使うための準備であると考えると、
thisポインタを他のクラスに渡すことは、安全に使うための準備が完了してないオブジェクトのメンバ関数を呼び出す手段を与えることになり、
危険ではないかと思うのですが、この方法は一般的に使われているのでしょうか?
360デフォルトの名無しさん:2008/02/08(金) 14:08:36
thisポインタを渡したクラスがコンストラクタが終了する前にthisの中身(つまり、コンストラクト中のオブジェクト)を変更/参照したりしないのなら問題ねーだろ。
361359:2008/02/08(金) 15:37:24
>>360
ありです。
渡す側は、渡す相手が変更/参照しないかを、
もらう側は、変更/参照しないことの保障を、気をつければOKですか。
362デフォルトの名無しさん:2008/02/08(金) 17:04:33
template限定子とやらを初めて知ったんですが、
どういうケースで必要なのかいまいちわかりません
363デフォルトの名無しさん:2008/02/08(金) 17:38:18
template限定子を書かなければエラーになる時
364デフォルトの名無しさん:2008/02/08(金) 18:10:31
>>362
依存名.???<....>
依存名->???<....>

のような場合に最初のangle bracketsはless than operatorなのか
templateの始まりなのかをコンパイラに知らせる必要がある。

依存名.template ???<....>
依存名->template ???<....>
365デフォルトの名無しさん:2008/02/08(金) 18:16:30
>>359
VCだと警告が出る。しかし便利。よく考えて使う。
366デフォルトの名無しさん:2008/02/08(金) 18:30:22
>>362,364
でも「プログラミング言語C++」中の限定子が必要な例をVC8に
食わせると限定子が無くても通る、というか限定子を付けると
エラーという(w
VS2008 では知らないけど。
367デフォルトの名無しさん:2008/02/08(金) 19:19:54
>>366
テンプレートに関してコンパイラベンダー固有の問題
があることは常識。そんなもんは勝手に調べろってこった。
368デフォルトの名無しさん:2008/02/08(金) 19:21:04
コンパイラによって切り替わるマクロを定義して対処するのは常識。
同様の目的で使われる typename も同様。
369デフォルトの名無しさん:2008/02/08(金) 19:27:24
MSが糞なのは常識
370デフォルトの名無しさん:2008/02/08(金) 19:30:40
VC8 でも通らなかったっけ?
371デフォルトの名無しさん:2008/02/08(金) 19:31:59
BOOST_WORKAROUND(BOOST_MSVC,...
で埋め尽くされているBoost
372デフォルトの名無しさん:2008/02/08(金) 19:39:58
スコットメイヤーズはBON JOVIに似ている
373デフォルトの名無しさん:2008/02/08(金) 19:40:49
日本人はC++標準化委員会に入れないの?
374362:2008/02/08(金) 20:45:14
>>364
おぉなるほど!

コンパイラの気持ちにならないといけないんですね
typenameとかもそうですね
375デフォルトの名無しさん:2008/02/08(金) 21:39:02
template 限定子はポリシーを入れ子にするときとか使うよね。
376デフォルトの名無しさん:2008/02/08(金) 23:56:15
fatal error LNK1104:コンパイラは、ファイルd3d9.libを開けません
とでてしまいビルドできません
手動でリンカにd3d9.libを設定しましたが無理でした
どなたか助けて
377デフォルトの名無しさん:2008/02/09(土) 00:00:15
>>376
残念、スレ違いですから。
378376:2008/02/09(土) 00:18:21
他で聞いてきます
379デフォルトの名無しさん:2008/02/09(土) 00:19:11
エスパーすると、cppとかのソースファイルが置いてある所にd3d9.libを置け
380デフォルトの名無しさん:2008/02/09(土) 10:40:29
いいのかそれで?
381デフォルトの名無しさん:2008/02/09(土) 11:30:13
Visual C++で使える任意精度数値計算ライブラリはありませんか?

もしくは、Linux用に書かれた(?)ライブラリをVisual C++で使うための
一般的な手順・方法というのはあるのでしょうか。

任意精度数値計算ライブラリとして
apflot, gmp 等を使えばよいらしいことまでは分かったのですが
インストールの手順で
configure、nmake 等のLinux系の単語が頻出し困惑しています。
こういうものはVisual C++では使えないのでしょうか。
382デフォルトの名無しさん:2008/02/09(土) 11:36:12
一般的な手順というものはないから、Google先生に聞くんですよ。
http://www.google.co.jp/search?hl=ja&q=GMP+Visual+C%2B%2B&lr=lang_ja
383381:2008/02/09(土) 12:17:06
>一般的な手順というものはない
これが分かっただけでも、よかったです。
お早い返答ありがとうございました。
384デフォルトの名無しさん:2008/02/09(土) 18:42:11
Linux系にカテゴライズされたnmakeにちょっとだけ同情した
385デフォルトの名無しさん:2008/02/10(日) 17:59:12
int i = 0;
int* void F() const{ return &i; }
が通らないんだけども、
Fの中じゃ何も変更してないのに、ポインタを返すものにはconst付けられないの?
386デフォルトの名無しさん:2008/02/10(日) 18:01:32
>>385
途中の void はなんだ?
あと const 付きの関数はクラスの非 static メンバとしてしか宣言できないよ。
387デフォルトの名無しさん:2008/02/10(日) 18:14:23
ごめんなさい。適当に端折りすぎました。

struct S{
int i;
int* F() const { return &i; }
};

S Sobj;
Sobj.F();

が通らないんです。
const int* から int*に変換できないとかで。
388デフォルトの名無しさん:2008/02/10(日) 18:25:23
const付き関数の中では、メンバ変数に全てconstがつくと思えばいい。
constオブジェクトからメンバ変数を非constで参照できたらまずいだろ。

試してないけど、workaroundは以下。
const int * F() const { return &i; }
int F() const { return i; }
mutable int i;
389デフォルトの名無しさん:2008/02/10(日) 20:34:44
>>387
Sobj.F();の呼び出しによりメンバー関数int* F() const;は
は以下のようにコンパイルされようとする。

//pseudo code
int* F(const S * const this) //result in compile error
{
return (&(this->i));
}

thisは constオブジェクトへのポインタゆえにthis->iの型は
const int となり、その結果 &(this->i) の型は const int*
となる。関数の戻り値は初期化のsemanticsであり、
int*をconst int*で初期化することはできないからコンパイルエラー。
390デフォルトの名無しさん:2008/02/10(日) 20:59:46
constの有無で多重定義可能だから、こういうこともできる。
int* F() { return &i; }
int const* F() const { return &i; }
std::vector::operator []なんかがこういうことをやっている。
391デフォルトの名無しさん:2008/02/10(日) 21:29:24
似たような関数を2つ定義することになるから
片方はキャストを駆使してもう片方を呼ぶようにしましょうってフサフサが言ってた。
tp://www.aristeia.com/images/sdm-big.jpg
392デフォルトの名無しさん:2008/02/10(日) 22:00:16
数少ないconst_castの出番
393デフォルトの名無しさん:2008/02/10(日) 22:08:12
>>391
やっぱBON JOVIに似てるわ
394デフォルトの名無しさん:2008/02/10(日) 23:12:56
サンクスです。
つーかすげーな、、、
>>389みたいなことはどうやったら解るの?
コンパイラでも一度書かないと無理かな。
395デフォルトの名無しさん:2008/02/10(日) 23:14:49
規格書を読むとか
396デフォルトの名無しさん:2008/02/10(日) 23:23:10
コンパイラコンパイラつくりゃそりゃかなり勉強になるだろな。
でもその前に絶対>>395だな
397デフォルトの名無しさん:2008/02/11(月) 00:55:16
398デフォルトの名無しさん:2008/02/11(月) 01:20:31
>>394
どう動いてるのかを普段から考えてればいいのさ。
1年も続けてれば大体の事は分かるようになる。
399デフォルトの名無しさん:2008/02/11(月) 01:45:00
関数オーバーロードはコンパイラの気持ちにならないと難しいね
400デフォルトの名無しさん:2008/02/11(月) 01:46:54
自分で実装するならどうするか、とか。
401デフォルトの名無しさん:2008/02/11(月) 02:55:48
あれくらい規格書にあたらなくても、ちょっとましな本を読めば書いてあると思う。
402デフォルトの名無しさん:2008/02/11(月) 11:11:12
>>401
どの本?
403デフォルトの名無しさん:2008/02/11(月) 12:38:10
確かに考えればわかるけど、自信もって答えれるレベルまではなれない・・・
確信が持てるレベルまで行くには、やっぱ規格まで手を出さないといけないんじゃない?
404デフォルトの名無しさん:2008/02/11(月) 13:04:02
10数年くらい前は内部モデルを詳細に解説した書籍が
結構あった(ほとんど洋書)んだけど最近はめっきり無いね。
残念なことだ。
405デフォルトの名無しさん:2008/02/11(月) 13:05:33
オレもADL位はちょっとわかるけど、その副作用とか人に説明できるレベルには理解してないな・・・
406デフォルトの名無しさん:2008/02/11(月) 17:04:50
//type.1
vector<BigSizeClass> GetHoge(){
 vector< BigSizeClass> tmp;
 // 非同期の要求を処理した結果を、いろいろtmpに追加
 return tmp;
}

vector<BigSizeClass> result = GetHoge();
と使うのと、

//type.2
void GetHoge( vector<BigSizeClass> &tmp ){
 //tmpに色々追加
}

vector<BigSizeClass> result;
GetHoge( result );

と使うの、どっちがいい?

一応、2番を使ってるんだけど、
なんか戻り値を使わず、参照を引数で渡して結果を得るのがC++じゃないなぁというか、気持ち悪いって思っちゃう。

407デフォルトの名無しさん:2008/02/11(月) 17:14:42
>>406
わざわざ BigSizeClass なんて書いてるんだから結論は出てるんだろ?
参照引数に結果を詰めるなんて C++ (98~2003) ではよくあること。

あと、 2 の関数を使って 1 の関数が実装できるから、効率が許すときだけ
1 の方を使うのもアリかもね。
408デフォルトの名無しさん:2008/02/11(月) 17:14:53
>>406
type1でいいんじゃない?
コードでパフォーマンスを見積もるなら、
BigSizeClassのコピーコスト、
GetHoge()の呼び出し頻度、
vectorの要素数
くらいないとわからんよ。
409デフォルトの名無しさん:2008/02/11(月) 18:50:07
構造体を継承したクラスは可能なんでしょうか?
typedef struct _test
{
 int count;
} test;

class extest : public test
{
public:
 extest(int i) { count = i; };
 virtual ~extest() {};
 int getCount() { return count; }
};

int main(int argc, char* argv[])
{
 extest ext(10);
 printf("getCount:%d\n", ext.getCount());
 return 0;
}

VC++2003では動作するのですが、C++仕様として合ってるかどうかが
不安で…。
410デフォルトの名無しさん:2008/02/11(月) 19:17:04
>>409
継承すること自体には問題ない。

ただし new extest(...) で生成したオブジェクトを test* を使って delete は
できないことに注意。このため private 継承にしてもいいなら、そっちのほうが安全。

あと、その例の構造体名 _test は予約名になるから、素直に struct test にしておくこと。
411デフォルトの名無しさん:2008/02/11(月) 19:27:45
>ただし new extest(...) で生成したオブジェクトを test* を使って delete は
>できないことに注意
??なんで?
例のtest構造体なら仮想デストラクタもいらないし・・・
412デフォルトの名無しさん:2008/02/11(月) 19:40:37
>>411
5.3.5 Delete p3 より
"if the static type of the operand is different from its dynamic type, the
static type shall be a base class of the operand's dynamic type and the static type shall have a virtual
destructor or the behavior is undefined."
413デフォルトの名無しさん:2008/02/11(月) 19:55:19
>>412
_test に仮想デストラクタ持たせれば済む話だと思う。
414デフォルトの名無しさん:2008/02/11(月) 20:01:34
>409-410 だと struct なのが問題の原因に見えるけど、
本当は test が virtual なデストラクタを持ってないのが原因ってことか。
415デフォルトの名無しさん:2008/02/11(月) 20:09:03
1. _test に仮想デストラクタを作る
2. _test を private あるいは protected 継承する

この2通りだな。
というか、構造体にする必要もないと思うのだが。
416409:2008/02/11(月) 20:11:30
>410-415
test構造体に仮想デストラクタを入れると、newした場合も
_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)というエラーは出なくなりました。
ただ、継承したい構造体が他のC言語ライブラリが提供するものなので、
継承ではなく包含の方向で考えていきたいと思います。
どうもありがとうございました。
417デフォルトの名無しさん:2008/02/11(月) 20:17:15
ついでに言うとグローバル名前空間内で _ が先頭につく識別語は
処理系用の予約語だから、_test じゃなくて test_ にしとけ。
418デフォルトの名無しさん:2008/02/11(月) 20:20:39
>>416
包含がアリなら private 継承も考えたほうがいいかもね。

_BLOCK_TYPE_IS_VALID の assert は問題の未定義動作を捕まえて
くれてるのかな?
419デフォルトの名無しさん:2008/02/11(月) 20:24:12
まあ、包含でいいなら包含でいいと思う。
無理に継承しなくても。
420デフォルトの名無しさん:2008/02/11(月) 20:35:30
メイヤーズが言ってたis implemented in terms of関係か。
継承せざるを得ない場合をのぞいては、包含のほうが良いと言ってたな。
421416:2008/02/11(月) 21:17:01
>>417
なるほど、了解しました。

>>418
すいません、private継承で動作確認した時に delete (test*)pext; のように
して同様のアサートが出てたんですが、 delete static_cast<test*>(pext);
とすることでコンパイル時チェックがかかるようになりました。

ただ、C言語ライブラリ側で構造体をmalloc/freeで確保/破棄するように
なっていて、継承を用いた場合、クラスと構造体双方のインスタンスの
生存期間の管理が複雑になりそうに思えたこともありましたので…。

_BLOCK_TYPE_IS_VALIDのassertはやはり仮想デストラクタが未定義と
いうことを示しているようです。

>417-420
あらためて、ありがとうございました。
422デフォルトの名無しさん:2008/02/11(月) 23:17:01
private 継承で test* にキャストできるか?
423デフォルトの名無しさん:2008/02/11(月) 23:30:24
>>422
クラス内ならできるな
424デフォルトの名無しさん:2008/02/11(月) 23:30:52
まあ、それはそうだけど。
425デフォルトの名無しさん:2008/02/12(火) 08:26:11
>>409
class extest : public test
{
private:
 test* ptr;
...

にしたほうがいいんじゃないか?
426425:2008/02/12(火) 08:34:14
継承が残ってた

>425
>>409
class extest
{
private:
 test* ptr;
...

にしたほうがいいんじゃないか?

427デフォルトの名無しさん:2008/02/12(火) 08:43:18
仮想関数が無ければ継承する意味は無いだろう
428デフォルトの名無しさん:2008/02/12(火) 08:58:03
>>427
んなこたない。
429デフォルトの名無しさん:2008/02/12(火) 10:41:36
>>427
protectedメンバーにアクセスする状況もある。
430デフォルトの名無しさん:2008/02/12(火) 18:40:44
それを言うなら「継承以外の選択肢があれば、無理に継承する必要はない」だな
431デフォルトの名無しさん:2008/02/12(火) 20:22:26
boost::noncopyable
432デフォルトの名無しさん:2008/02/12(火) 23:28:01
>>406
ちょっと遅レスだけど、俺も前に同じこと悩んだ。
それで考えたのがmove semanticsっぽい感じでtype.1のコピーコストを無くす方法

template<class T> class move_val {
  T v;
public:
  move_val(){}
  move_val(move_val<T>& o){ swap(v,*o); }
  move_val(T& o){ swap(v,o); }
  void operator=(move_val<T>& o){ swap(v,*o); }
  void operator=(T& o){ swap(v,o); }
  T& operator*(){ return v; }
};
move_val<vector<BigSizeClass> > f1(){
  vector<BigSizeClass> v;
  v.push_back(BigSizeClass());
  v.push_back(BigSizeClass());
  return v;
}
void f2(){
  move_val<vector<BigSizeClass> > v1 = f1();
  move_val<vector<BigSizeClass> > v2 = v1;
  cout <<"v1:"<<(*v1).size()<<" v2:"<<(*v2).size()<< endl;
}
433デフォルトの名無しさん:2008/02/13(水) 07:09:49
>>432
よくわからん。詳しい説明きぼん
434デフォルトの名無しさん:2008/02/13(水) 11:05:34
テンプレートを使ってでかいメモリ領域を効率よく移動させるためのラッパークラス
435デフォルトの名無しさん:2008/02/13(水) 11:50:20
>>433
経緯から。
vector<BigSize> v1;
//vに要素追加

//v2=v1 は v2=f1()と基本的には同じ。
//ここでv1の中身まるごとコピーされる。
//コピー重杉氏ね。
//でもv2がこの先生きのこればv1はいらない
vector<BigSize> v2 = v1;

//swapすればおk
vector<BigSize> v2;
swap(v2,v1);

//毎回swap書くの面倒だしv2=v1みたいに書きたい。
//なのでコピーコンストラクタ・代入演算子で
//勝手にswapするテンプレートを用意

void f2(){
  //f1()で作られたvとv1がswapされる
  //vは空になる
  move_val<vector<BigSize> > v1 = f1();
  //v1とv2がswapされる
  //v1は空になる
  move_val<vector<BigSize> > v2 = v1;
  //最終的にf1()内で確保されたメモリはv2が責任を持つ
  cout <<"v1:"<<(*v1).size()<<" v2:"<<(*v2).size()<< endl;

} //v2死亡、f1()内で作られた要素が破棄されメモリも解放
436435:2008/02/13(水) 12:07:33
補足。
非const参照引数だと一時オブジェクトを受け取れなかったりするけど
VC++だとコンパイル通るので↑では気にしてない。

ちゃんとC++するならauto_ptr_refみたいな
proxyを経由させないといけない。
437デフォルトの名無しさん:2008/02/13(水) 13:06:17
Mojoったらいいのに。
438デフォルトの名無しさん:2008/02/13(水) 13:58:21
それなんてMOJOって書こうとしたら先に書かれてた
439デフォルトの名無しさん:2008/02/13(水) 14:36:14
復習をかねて、Mojo っぽく書いてみた。

template <typename T> class Vector;

template <typename T> class TemporaryVector {
public:
    explicit TemporaryVector(Vector<T>& v) : v_(&v) {}
    Vector<T>& get() { return *v_; }
private:
    Vector<T>* v_;
};
   
template <typename T> class Vector : public std::vector<T> {
public:
    Vector() {}
    Vector(TemporaryVector<T> tmp) { std::swap(*this, tmp.get()); }
    operator TemporaryVector<T> () { return TemporaryVector<T>(*this); }
};

TemporaryVector<BigClass> f1() {
    Vector<BigClass> v;
    v.push_back(BigClass());
    return v;
}

int main() {
    Vector<BigClass> v = f1();
    std::cout << v.size() << std::endl;
}
440デフォルトの名無しさん:2008/02/13(水) 15:28:17
コンテナ自体も型パラメータ化して、
vectorに限定しない形で書いてもらえると嬉しい・・・
441デフォルトの名無しさん:2008/02/13(水) 16:41:48
>>440
それくらい自分で書けよw
442デフォルトの名無しさん:2008/02/13(水) 17:30:12
>>441
Mojoっての知らないからお願いしてみたけど、
考えてみたら超簡単だったw
スマン。

ところで、実行してみたんだけど、これどこかバグってない?
f1の戻り受け取りでコピーコンストラクタ動いちゃうのと、
その際、デストラクタ後のインスタンスが参照されるんだけど・・・。
443デフォルトの名無しさん:2008/02/13(水) 18:25:15
f1の戻り値のローカルなVector<BigClass>オブジェクトを
explicit TemporaryVector(Vector<T>& v) : v_(&v) {}
で変換するときに、もうゴミになってるポインタを設定
してるとか?
444デフォルトの名無しさん:2008/02/13(水) 18:31:52
Modern C++ Designだが、2章のCompileTimeCheckerを使った
マクロでいきなりコンパイル通らなくて、やる気を削がれるんだけど。
みんなどうした?
445デフォルトの名無しさん:2008/02/13(水) 18:32:44
本が出版された当時はsizeofに関数呼び出しをパラメータに
渡せたのか?
446デフォルトの名無しさん:2008/02/13(水) 18:45:51
struct One { char x ; } ;
struct Two { char x[2] ; } ;

One f(int) ;
Two f(...) ;

void v()
{
  std::cout << sizeof( f(hoge) ) << std::endl ;
}

こういうやつか?
447デフォルトの名無しさん:2008/02/13(水) 18:51:49
>>446
いや、それは戻り値に評価されるから合法だと思うんだ。よくやるよね。
そうではなくて、コンストラクタの呼び出しをsizeofの引数に渡してる
んだよね。こういうやつ。

template<bool> struct CompileTimeChecker {
CompileTimeChecker(...);
};

template<> struct CompileTimeChecker<false> {

};

//macro definition
#define STATIC_CHECK(expr, msg) \
{ \
class ERROR_##msg{}; \
(void)sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg()))); \
}

sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg())));
が怒られる。
448デフォルトの名無しさん:2008/02/13(水) 18:53:35
で、こういう風に使う。

template<typename To, typename From>
To safe_reinterpret_cast(From from) {
STATIC_CHECK(sizeof(From) <= sizeof(To), Destination_Type_Too_Narrow)
return reinterpret_cast<To>(from);
}

int _tmain(int argc, _TCHAR* argv[])
{
int i = 0;
int* somePointer = &i;
char c = safe_reinterpret_cast<char>(somePointer);

return 0;
}
449デフォルトの名無しさん:2008/02/13(水) 19:02:37
streambufを複数のストリームで共有することは可能ですか?
本来ストリームを操作することを想定していない関数の中で
書式を設定してメッセージを出力したいのですが、
copyfmtで書式の情報を退避するのも例外対策などを考えると面倒なので、
次のように書きたいのです。
#ifdef DEBUG
    std::ostream(std::cerr.rdbuf()) << "f(x)=" << std::setprecision(6) << f(x) << std::endl;
#endif
450デフォルトの名無しさん:2008/02/13(水) 19:40:03
>>449
tight couplingのことでしょ?
(ストリームバッファの共有)
できるよ。

ostream prec6_cerr(cerr.rdbuf());
prec6_cerr.precision(6);

prec6_cerr << "f(x)=" << f(x) << endl;

これでcerrとprec6_cerrは同じバッファを共有するけど
フォーマットはstreambufではなくostreamに設定される
から別個のフォーマット扱えるとオモタ。
451デフォルトの名無しさん:2008/02/13(水) 21:06:59
>>447
これって違法なのかねえ。
よく分かんないや。

とりあえず、

sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg())));



sizeof((CompileTimeChecker<(expr) != 0>)((ERROR_##msg())));

にすればいけるね。
関数風キャストから C 風キャストに変更しただけだが。
452デフォルトの名無しさん:2008/02/13(水) 21:19:53
>>432の方法でtype.1のコピーコスト消えるの?
453デフォルトの名無しさん:2008/02/13(水) 21:28:29
>>451
thx。なるほど。

>これって違法なのかねえ
Comeauでもハッキリとコンパイルエラーになるんだよね。

static_castで行くことにする。
(void)sizeof(static_cast<CompileTimeChecker<(expr) != 0> >((ERROR_##msg())));


あと、何故sizeofの結果をvoidへキャストする必要があるかだけど、
もしキャストしないとComeauでは警告が出る。何でvoidへキャスト
すると警告が消えるんだろう?

キャストを省略した場合は以下の警告。
"ComeauTest.c", line 15: warning: expression has no effect
STATIC_CHECK(sizeof(From) <= sizeof(To), Destination_Type_Too_Narrow)
^
まあ、でもよくこんなこと考え付くわ。面白いけど使いどころあるかな。
454デフォルトの名無しさん:2008/02/13(水) 21:31:12
0;

とかいう式と似たようなもんだから、
void でキャストして明示的に値を捨てないと
警告出すコンパイラもある。
455デフォルトの名無しさん:2008/02/13(水) 21:32:29
>>449
boostのio_state_savers使うのがオススメ
456デフォルトの名無しさん:2008/02/13(水) 21:39:45
>>454
なるほど。
voidへのキャストって値を捨てるという意味になるのか。
void*はよく見るけど、生のvoidってあまり見ない。
しつこくてすまんが、明示的に値を捨てるという使い方も
voidの機能の一つなんですか?
457デフォルトの名無しさん:2008/02/13(水) 21:44:40
C++ではあまり見掛けないけど古いCのコードにはよくある。
458デフォルトの名無しさん:2008/02/13(水) 21:45:04
>>456
うい。例えば

#define STATIC_ASSERT(expr) ((int(*)[(expr) ? 1 : -1])0)

こういうタイプの静的アサーションマクロがあったとすると、

int (*p)[1] = STATIC_ASSERT(true);

みたいにしてその値を使えてしまう。
そこで、

#define STATIC_ASSERT(expr) ((void)(int(*)[(expr) ? 1 : -1])0)

と void にキャストすると、そういうことができなくなる。
459デフォルトの名無しさん:2008/02/13(水) 21:47:38
>>457
printf の戻り値を void でキャストして捨てないと
コードチェックに引っかかることがあるというアレか。
460デフォルトの名無しさん:2008/02/13(水) 21:57:12
>>457
今考えると、
洒落たテクニックの部類に入りますかね。

>>458
確かに、exprがtrueでヌルポインタ定数0を配列へのポインタ
(int(*)[1])0
に変換できると、今の場合は型が一致するから代入できてしまう。
そこで、voidが不完全型でvoid型変数は定義できないし、どんな型
とも代入互換性が無いことを利用してエラーにすると。

ありがとうございました。よく分かりました。
461デフォルトの名無しさん:2008/02/14(木) 00:36:45
>>459
そういえば
sprintf(buf,…);
len = strlen(buf);
というコードを書くバカが多いよな。
462デフォルトの名無しさん:2008/02/14(木) 00:50:38
案外最初に習得する関数だと、manとか見ないんだよな。
特にprintf系は機能多すぎだし、読むのメンドウで。
463デフォルトの名無しさん:2008/02/14(木) 01:19:12
MOJOとMove Constructorって別物?
464デフォルトの名無しさん:2008/02/14(木) 01:31:21
同じじゃね?
どっちにしろC++09で右辺値参照入れば用済みさ。
465デフォルトの名無しさん:2008/02/14(木) 02:04:22
Boost.Moveを頑張って使ったが
コンパイラの最適化で十分らしく何の効果もなかった
466デフォルトの名無しさん:2008/02/14(木) 02:13:32
どう使ったのかkwsk
467デフォルトの名無しさん:2008/02/14(木) 06:44:55
>>452
struct BigSizeClass {
    int n;
    BigSizeClass(int arg_n):n(arg_n){
        cout << "BigSizeClass("<<n<<" : "<<this<<")" << endl;
    }
    BigSizeClass(const BigSizeClass& o):n(o.n){
        cout << "copy BigSizeClass("<<n<<" : "<<this<<")" << endl;
    }
    void operator=(const BigSizeClass& o){
        n=o.n; cout << "operator=("<<n<<" : "<<this<<")" << endl;
    }
    ~BigSizeClass(){ cout << "~BigSizeClass("<<n<<" : "<<this<<")" << endl; }
};
のようにしてトレースすれば分かる、最後のpush_back以降に
BigSizeClassのコンストラクタや代入は発生しない。
vectorのswapはポインタとサイズの交換なので要素や要素数に関係無くすぐ終る。

ちなみに>>465の言う通り、v1 = f1();のような所は
戻り値の最適化で、普通にvector直に使っても余計なコピーが消えたりするケースもある。
※v1に直にpush_backしてるみたいになる。
468デフォルトの名無しさん:2008/02/14(木) 06:49:54
std::unique_ptrとstd::moveが待ち遠しい。
469デフォルトの名無しさん:2008/02/14(木) 08:14:59
コンテナの選択に困りました。
・ポリモフィズムしたい
・挿入/削除が高頻度
・何種類かのソートが高頻度

理想はboost::ptr_containerを使ったboost::multi_indexだと思うんですが、どうやらありません。
どのコンテナを使うべきだと思いますか?
470デフォルトの名無しさん:2008/02/14(木) 08:39:39
>>469
コンテナの具体的な用途に絞れば ptr_container が担当する部分を自分で書くのは
あまり難しくないだろうから、ポインタを要素型にした multi_index かな。
471デフォルトの名無しさん:2008/02/14(木) 08:42:25
>>469
std::vectorでじゅうぶんだろ
472469:2008/02/14(木) 09:46:52
レスthx

>>470
ptr_containerを使えないのは残念ですが、その方法になってしまいますか。
>>471
vectorを使うなら、ptr_vectorを使いたいです。
473デフォルトの名無しさん:2008/02/14(木) 09:49:14
>>469
ソートが高頻度という要件で multi_index は要らんだろ。
何種類かのキーによるアクセスが高頻度ということなら欲しくなるけど。

multi_index が要らないなら ptr_list かな。 >470 と同じ理由で std::list で
十分とも言えるそうだけど。
474469:2008/02/14(木) 10:27:06
>>473
"何種類かのソート"と書いたのは、std::sortに渡す関数オブジェクトが何種類かあるという意味です(連想配列ならキー)。

std::vectorやstd::listで十分というのは、
ptr_containerを使うよりstdのコンテナを使うメリット(というよりptr_containerのデメリット?)が何かあるんでしょうか?
475デフォルトの名無しさん:2008/02/14(木) 10:50:43
>>474
std::sort
だったらランダムアクセスイテレータを持つコンテナに
限定されてしまわないかい?
476469:2008/02/14(木) 11:00:26
>>475
std::sortを絶対に使わないとダメというわけではなくて、std::sortを使えるコンテナにstd::sortを使った場合の話です。
listならメンバ関数のsortを使えばいいし、mapなら(複数のキーでアクセスしたいので)multi_indexですね。
477デフォルトの名無しさん:2008/02/14(木) 11:45:09
std::vectorみたいにランダムアクセスできて、かつメモリ領域が連続していなくてもいいコンテナってありますか?
要するに要素本体はどこか別のところに保持しておいて、それへのアクセス用ポインタをstd::vectorに突っ込んであるというような。
478デフォルトの名無しさん:2008/02/14(木) 12:46:21
「要するに」の前後で要件が異なってるような気もするけど、
どちらを探してるの?
479デフォルトの名無しさん:2008/02/14(木) 12:46:55
2行目はともかく、1行目はstd::dequeでいいよな。
480デフォルトの名無しさん:2008/02/14(木) 12:56:56
2行目ならboost::ptr_vectorかな。
481デフォルトの名無しさん:2008/02/14(木) 13:09:25
2つ併せて、boost::ptr_deque じゃない?
482デフォルトの名無しさん:2008/02/15(金) 02:47:53
wchar_t* Replace(wchar_t* src, wchar_t* before, wchar_t* after){
size_t src_length = wcslen(src); //元文字列の長さ
size_t before_length = wcslen(before); //検索文字列の長さ
if(src_length < before_length || before == L"" || before == after) return src;

size_t after_length = wcslen(after); //置換文字列の長さ
int shift = after_length - before_length; //置換による移動数
wchar_t *start = src; //検索開始位置
wchar_t *hit; //見つかった位置
int match; //マッチ回数

//マッチ回数を求める
for(match = 0; (hit = wcsstr(start, before)) != NULL; match++) start = hit + before_length;
if(match == 0) return src;

//長くなる分だけメモリを確保
if(shift > 0){
wchar_t *tmp;
if((tmp = (wchar_t *)realloc(src, (src_length + shift * match + 1) * sizeof(wchar_t))) != NULL) src = tmp;
else return src;
}

//置換部
start = src;
for(int i = 0; i < match; i++){
hit = wcsstr(start, before);
wmemmove(hit + after_length, hit + before_length, wcslen(hit) - before_length + 1);
wmemmove(hit, after, after_length); //置換
start = hit + after_length; //次の検索開始位置
}
return src;
}
483デフォルトの名無しさん:2008/02/15(金) 02:49:23
非MFC環境下で文字列の置換を行えるようにするために
wchar_t型の、(原文, 検索ワード, 変換ワード)を指定すると
まず原文中に検索ワードが何回出てくるかを調べ
置換後に文字列が長くなる場合はその分メモリを追加確保し
その後検索ヒット回数だけ置換を行うという
>>482の関数を下記のように使いたいと思い

size_t text_length = GetWindowTextLengthW(edit) + 1;
wchar_t *src = new wchar_t[text_length];
GetWindowTextW(edit, src, text_length);
SetWindowTextW(edit, Replace(src, L"a", L"aa"));
               ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
ひとまずそれっぽく動くようにはなったのですが、いくつか質問がありまして、
1,まず第一に整合性が保たれているかという点
 置換後に文字数が変わる置換や、「ソ」で文字化けする問題は大丈夫でしたが、
 その他特定の場合にエラーが出る可能性はありますか?

2,原文"aaa" 検索ワード"a" 置換ワード"" とした場合
 結果は""となりますが、このとき短くなる分だけ
 reallocでメモリ幅を縮めたほうが良いのでしょうか?
 (縮めてみようかと思ったところエラーが出たので、現在は長くなる場合しかreallocしてません)

3,VC++6.0でコンパイルしていますが、これはWin9x系でも正常に動くのでしょうか?
 (Win9xでwchar_t型が一部動かないというのを見たので)

4,検索ループと置換ループを分けたのは、
 reallocを一度で済ませる事で速度的に向上が見られたためなのですが、
 まだ文字数が増えたときの変換が遅い気がするので
 他に速度を早くする方法があれば教えてください。

よろしくお願いします。
484デフォルトの名無しさん:2008/02/15(金) 03:53:00
>>483
_TマクロとSTLのstring/wstringを使って、Unicode版とMBCS版を作ればいいんじゃないか?
485デフォルトの名無しさん:2008/02/15(金) 04:37:26
RVOが出てきちゃって>>432の方法がうまくいかん
486デフォルトの名無しさん:2008/02/15(金) 05:48:16
>>485
非const参照の一時オブジェクトで怒られるとかじゃなくて、RVOで?
RVOがあってもv2=v1;には影響ないはずだけど・・・。
487デフォルトの名無しさん:2008/02/15(金) 05:54:50
#include <vector>
#include <iostream>
#include <tchar.h> //_tmain
#include <conio.h> //_getch

using std::vector;
using std::cout;
using std::endl;
using std::swap;

#include >>467

template<class T> class move_val {
  T v;
public:
  move_val(){}
  move_val(move_val<T>& o){ swap(v,*o); }
  move_val(T& o){ swap(v,o); }
  void operator=(move_val<T>& o){ swap(v,*o); }
  void operator=(T& o){ swap(v,o); }
  T& operator*(){ return v; }
};
move_val<vector<BigSizeClass> > f1(){
  vector<BigSizeClass> v;
  v.reserve(2);
  v.push_back(BigSizeClass(0));
  v.push_back(BigSizeClass(1));
  cout <<"--push end"<< endl;
  return v;
}
488続き:2008/02/15(金) 05:58:32
void f2(){
  move_val<vector<BigSizeClass> > v1 = f1();
  move_val<vector<BigSizeClass> > v2 = v1;
  cout <<"v1:"<<(*v1).size()<<" v2:"<<(*v2).size()<< endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
  f2();
  _getch(); //デバッグ実行でコンソールを残すため
  return 0;
}


結果
BigSizeClass(0 : 0012FC6C)
copy BigSizeClass(0 : 00368BA0)
~BigSizeClass(0 : 0012FC6C)
BigSizeClass(1 : 0012FC78)
copy BigSizeClass(1 : 00368BA4)
~BigSizeClass(1 : 0012FC78)
--push end
v1:0 v2:2
~BigSizeClass(0 : 00368BA0)
~BigSizeClass(1 : 00368BA4)

一応VC++2005 Expressでのソースと実行結果を。
push end後にコピーは起こらず、v1も空になり、v2破棄で中身が破棄される。
489デフォルトの名無しさん:2008/02/15(金) 12:01:58
ちょっと修正。

VC++2005 Expressだと非const参照で一時オブジェクトを受けても
コンパイル出来てしまうけど、(本当はエラーが正しい)
警告レベル4(/W4)にすれば指摘されるように出来たので、
auto_ptr_refみたいに代理経由するようにした。

>>487のmove_valを修正
template<class T> class move_val {
  ... //T& operator*()まで省略

  //非const参照で一時オブジェクトを受け取る対応。
  template<class R> struct tmp_ref { R* p; tmp_ref(R* ap):p(ap){} };
  move_val(tmp_ref<move_val<T> > r){
    cout<<"ref受け取り:"<<r.p<<""<<endl; //確認用
    swap(v,r.p->v);
  }
  void operator=(tmp_ref<move_val<T> > r){ swap(v,r.p->v); }
  operator tmp_ref<move_val<T> >(){
    cout<<"ref化:"<<this<<""<<endl; //確認用
    return tmp_ref<move_val<T> >(this);
  }
  ~move_val(){ cout<<"~move_val:"<<this<<""<<endl; } //確認用
};
490デフォルトの名無しさん:2008/02/15(金) 12:05:56
swigってstlのvectorなどには対応してるみたいだけど
boost.ublas.matrix
とかは対応してるの?
491483:2008/02/15(金) 12:11:22
>>484
stringを使っていないのは、
GetWindowTextからSetWindowTextまで型変換をせずに済ませたいためです。
また、Unicode版・MBCS版と2種類作らずに、
1つのプログラムでNT系+9x系と使える方法を考えてます。
492デフォルトの名無しさん:2008/02/15(金) 12:42:37
>>491
デストラクタにメモリの解放を任せるため、
それでも vector くらいは使った方がいいよ。
あるいは realloc とか使うのであれば、
自作のコンテナかスマートポインタかを作るか。

vector で受ければ、要素の挿入も自動で出来るからプログラム楽だし。
ただ、メモリを縮小することは基本的にはできないかな。
(resize でメモリ少なくしても、メモリの再確保は行われない)
もう1つバッファ作ってそこにコピーするならいけるけど。

wstring で受けた方が replace メンバ関数があるから便利だけど、
メモリの連続性は多分全てのコンパイラで保証されてるとは思うけど、
ヌルターミネータの扱いがどう実装されてるか
(常にヌルターミネータを付ける実装になっているか、
 それとも c_str 実行時にヌルターミネータを付ける実装になっているか)
の問題がよく分からないので、やめといた方が無難。

あと、効率を求めるならまた他の実装もあると思う。

その他の特定の場合にエラーが出るかどうかは、
Replace の中身次第やね。これ以上は何とも言えん。
493デフォルトの名無しさん:2008/02/15(金) 13:29:54
c++でreallocを使うのは止めた方がいい。
あとシステムのAPIなどはともかく、
内部の加工などで\0終端を前提として書いたり、
前提とする関数を使ったりするのも止めた方がいい。
494デフォルトの名無しさん:2008/02/15(金) 13:36:24
まあ POD 型を扱う分には realloc 使っていいと思うけどね。
POD 型でも内部に内部へのポインタ持ってたらアレだけど、
それは C でも同じ事だし。
495デフォルトの名無しさん:2008/02/15(金) 14:39:47
C++だと例外安全考えないといけないからね、
分かった上で使ってる人なら良いんだけど・・・。

realloc使った上で例外安全にするのは別に難しくはないけど、
reallocとかmallocとか使ってるようなCっぽいソースは
大体例外安全でない兆候だと思う。

Cで書かれたライブラリを使う(C++ → C方向のみ)とか、
独自アロケータ実装とかなら大丈夫だろうけど。

それに>>482>>483したらrealloc分が普通にリークするし、
483のnewの後、throwする可能性のある関数呼んだら
同じくnew分がリークする。

>>492がvectorとかスマートポインタ勧めてるのも
そういうことだと思う。
496デフォルトの名無しさん:2008/02/15(金) 14:44:30
つまるところ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を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。