C++相談室 part60
レス数が1000を超えています。これ以上書き込みはできません。
0001デフォルトの名無しさん
2008/01/11(金) 18:43:34ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。
0002デフォルトの名無しさん
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)に対応。
0003デフォルトの名無しさん
2008/01/11(金) 18:44:42Effective STL
http://www.amazon.com/exec/obidos/ASIN/0201749629/
http://www.amazon.co.jp/exec/obidos/ASIN/4894714108/ (翻訳)
Modern C++ Design
http://www.amazon.com/exec/obidos/ASIN/0201704315/
http://www.amazon.co.jp/exec/obidos/ASIN/4894714353/ (翻訳)
C++ Templates
http://www.amazon.com/exec/obidos/ASIN/0201734842/
C++ Template Metaprogramming
http://www.amazon.com/exec/obidos/ASIN/0321227255/
0004デフォルトの名無しさん
2008/01/11(金) 18:44:58[Boost]
Boost http://www.boost.org/
(日本語) http://www.kmonos.net/alang/boost/
(日本語) http://shinh.skr.jp/boost/
[標準ライブラリ]
SGI-STL http://www.sgi.com/tech/stl/
STLport http://stlport.sourceforge.net/
GNU libstdc++ http://gcc.gnu.org/libstdc++/
Apache STDCXX http://incubator.apache.org/stdcxx/
STLFilt http://www.bdsoft.com/tools/stlfilt.html
(日本語) http://www005.upp.so-net.ne.jp/episteme/html/stlprog/
(日本語) http://www.wakhok.ac.jp/~sumi/stl/
[Loki]
http://sourceforge.net/projects/loki-lib/
LokiPort-MSVC6sp5 http://fara.cs.uni-potsdam.de/~kaufmann/?page=lokiport
0005デフォルトの名無しさん
2008/01/11(金) 18:45:19環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない
すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?
#include <stdafx.h>
後死ね。
言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
0006デフォルトの名無しさん
2008/01/11(金) 18:45:37C++相談室 part59
http://pc11.2ch.net/test/read.cgi/tech/1192866305/
0007デフォルトの名無しさん
2008/01/11(金) 19:00:390008デフォルトの名無しさん
2008/01/11(金) 19:10:02派生させた、インスタンスの消滅(delete)は何処でやったらいい?
基底のデスクトラクタは、Effective C++ 新訂3版、宜しく
virtualで宣言してるんだけど?
0009デフォルトの名無しさん
2008/01/11(金) 19:12:26内容はどうだった?
0010デフォルトの名無しさん
2008/01/11(金) 19:15:00俺はstd::auto_ptrに突っ込んでいるが。
0011デフォルトの名無しさん
2008/01/11(金) 19:53:48とりあえず
std::auto_ptr
boost::shared_ptr
は、なしで宜しくオナガイシマス
0012デフォルトの名無しさん
2008/01/11(金) 20:02:580013デフォルトの名無しさん
2008/01/11(金) 20:14:00kuwasiku
0014デフォルトの名無しさん
2008/01/11(金) 20:18:29適当でいいなら適当なソース読め。
0015デフォルトの名無しさん
2008/01/11(金) 20:20:26>>適当でいいなら適当なソース読め。
どこにある?
0016デフォルトの名無しさん
2008/01/11(金) 20:41:09auto_ptrならコンパイラが持ってるかも知れん。検索しろ。
開発環境書かなきゃディレクトリなんてわかるか。
0017デフォルトの名無しさん
2008/01/11(金) 20:50:05std::tr1::shared_ptrという抜け穴w
0018デフォルトの名無しさん
2008/01/11(金) 20:54:220019デフォルトの名無しさん
2008/01/11(金) 21:08:13LokiはModern C++ Designに載ってるライブラリだろうが
なもん判るか、ぼけ
ってゆうか、予想はしてたが、Prototype パターンで、派生させた、
インスタンスを消滅させるのって、やっかいなんだな
0020デフォルトの名無しさん
2008/01/11(金) 21:15:180021デフォルトの名無しさん
2008/01/11(金) 21:28:03その和と積と差を求めるプログラムを作りたいんだけど、
50桁も入力できない!!!
20桁もできない
どうすれば入力できますか?
0022デフォルトの名無しさん
2008/01/11(金) 21:29:37べつにPrototypeに限らん。
生成パターンで生成させたオブジェクトは皆同じ。
元々JavaとかC#に向いた手法だよな。
0023デフォルトの名無しさん
2008/01/11(金) 21:30:310024デフォルトの名無しさん
2008/01/11(金) 21:32:05入力を文字列として読み取り、ひと桁ずつを配列に入れる。
あとはお前が筆算をやる要領でひと桁ずつ下の桁から加算する。
10を超えたら次の桁(=次の配列)に桁上げする。
単純だけど、こんなんでも一応実現できる。
0025デフォルトの名無しさん
2008/01/11(金) 21:41:12マルチ
今宿題スレに行ってるな
0026デフォルトの名無しさん
2008/01/11(金) 21:48:00>>22へ
個人的な意見だが、ポインタ使って、ヒープにメモリ確保するのって
後始末が煩雑だから、嫌なんだよね、静的にインスタンスが、作れないものかな・・・
0028デフォルトの名無しさん
2008/01/11(金) 22:34:5929じゃなくて
>>24
のまちがいでした。。
あと、できればプログラム詳しく教えてほしいんですが(ノ_・。)
配列にいれて足していくってどうやればいいですか???
>>23
ぐぐります!!
0029デフォルトの名無しさん
2008/01/11(金) 23:12:53マルチしてるのでどっちか取り下げないか?
助けてやろうにもどっちで助ければいい?
0030デフォルトの名無しさん
2008/01/11(金) 23:20:490031デフォルトの名無しさん
2008/01/11(金) 23:23:230032デフォルトの名無しさん
2008/01/12(土) 11:05:00class NLComponent
{
virtual NLComponent * clone() const = 0 ; // クローンメソッド
};
基底クラスに、純仮想関数を宣言して、派生クラスでインスタンスを生成する方法が
載っているんだけど、一例で、ディスク上に保存されている、オブジェクトを
std::istream strを引数にとるコンストラクタで渡してやってるんだけど
これって、なんかおかしい気がする、理由は、コンストラクタで例外が起きたらどうなるんだ?
どう思うよモマイラ
0033デフォルトの名無しさん
2008/01/12(土) 11:15:5832の質問は却下します、スマン
0034デフォルトの名無しさん
2008/01/12(土) 17:50:36おいおい、自分で書いておいて却下するなよ。
0035デフォルトの名無しさん
2008/01/13(日) 23:53:36テキストファイルから文字列を読み込んでいるのですが、CStdioFileなどを使った読み込みですと、1行ずつ読み込むしかありません。
これを、1行ではなく指定の区切り文字まで読み込む、というのをやりたいのです。
具体的に言うと、「。」がくるまで読み込みをやりたいと思っています。
今日は晴れです。明日も晴れです。
という文章を読み込む場合、最初の読み込み時では
今日は晴れです。
が読み込まれ、次の読み込みで
明日も晴れです。
が読み込まれるようにしたいと考えています。
何か標準のライブラリでこのようなものはないでしょうか? よろしくお願いします。
0036デフォルトの名無しさん
2008/01/14(月) 00:14:400037デフォルトの名無しさん
2008/01/14(月) 00:35:49getline(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"明日も晴れです"
0039デフォルトの名無しさん
2008/01/14(月) 21:44:28入力支援機能を実現する Emacs Lisp プログラムが
用意されているのでしょうか?
単純なキーワード色づけは今も使っているのですが,
もっと詳細な情報を得たいと思っています.
0040デフォルトの名無しさん
2008/01/14(月) 23:51:44クラスオブジェクト(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が出来上がってしまい、 スマートな実装ではない気が
しています。。。 上記のようなケースは どのように実装するのが適切なのでしょうか。
ご教授をお願いします。
0041デフォルトの名無しさん
2008/01/14(月) 23:51:440042デフォルトの名無しさん
2008/01/14(月) 23:56:00>>40
抽象度が高すぎてなんともいえないな…。
CTestXXはラッパークラスなんかね?
それとも唯のコンテナか…エスパーに任せる。
0043デフォルトの名無しさん
2008/01/14(月) 23:58:18各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{};
0044デフォルトの名無しさん
2008/01/15(火) 00:02:24ある。無論標準装備ではない。
0045デフォルトの名無しさん
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();
という感じ
現在これをテンプレートで実現してて
(続く)
0046デフォルトの名無しさん
2008/01/15(火) 00:29:32void** 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]));
}
(続く)
004740
2008/01/15(火) 00:55:05>>42
初学ゆえ説明足らずで申し訳ありません。
CTestxxはCObjxxの機能を有するという形で実装したいと考えています。
CObjxxとCTestxxの間にラッパクラスを挟むべきか、それともよりよい
実装方法があるのか、そもそもCObjxxは包含すべきものなのか、
というところを悩んでいます。なんかうまく説明できなくてすみません。。。
>>43
なるほど。この方法だとCTestxxはCObjxxの機能を有しつつ、必要な部分だけを
公開できそうです。貴重なご意見ありがとうございます。
0048デフォルトの名無しさん
2008/01/15(火) 02:16:35> 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のまま解決したいと思っています。
よろしくお願いいたします。
0050デフォルトの名無しさん
2008/01/15(火) 22:27:52--input-charsetじゃなくて-finput-charsetだった希ガス
つーかすれ違い
005148
2008/01/15(火) 23:53:54ありがとうございます。
--input-charsetは-finput-charに展開されていたと思うので確か同じことだと思います。
GCCスレに同じ質問投げてきます。失礼しました。
0052デフォルトの名無しさん
2008/01/16(水) 16:52:57で作りたいのですが、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)
};
005352
2008/01/16(水) 16:56:53const boost::array<Row, YSIZE> plane
は手書きで初期化します。一般化したいのはRowだけです
0054デフォルトの名無しさん
2008/01/17(木) 16:57:59Borland社のフリーのコンパイラを使用してるのですが
#defineをmakefileでのコンパイラ時に宣言するときはどのような記述がいるのでしょうか?
0055デフォルトの名無しさん
2008/01/17(木) 17:08:05-D名前
-D名前=文字列
0056デフォルトの名無しさん
2008/01/17(木) 17:10:49無事できました、ありがとうございます
0057デフォルトの名無しさん
2008/01/17(木) 17:56:37ほのぼのした.
0058デフォルトの名無しさん
2008/01/17(木) 23:25:38今日から勉強しようと今、Visual C++ 2008 Express Editionをインストール中。
ここまでOKです。
0059デフォルトの名無しさん
2008/01/17(木) 23:27:07帰ってよし
0060デフォルトの名無しさん
2008/01/18(金) 01:44:30お前すごいな! VC2008をインスコしたのか
おれは、コンピラーすらインスコしてないよ
コンピラーぐらい、OSにおまけで付けて欲しいよな
0061デフォルトの名無しさん
2008/01/18(金) 03:00:22C#とかVB.NETのコンピラーがおまけで付いていますよ、と。
0062デフォルトの名無しさん
2008/01/18(金) 10:03:240063デフォルトの名無しさん
2008/01/18(金) 10:21:21http://d.hatena.ne.jp/niitsuma/20080114
他にも何か有用なサイトをご存じの方
お教えいただけると幸せです
0064デフォルトの名無しさん
2008/01/18(金) 14:16:250065デフォルトの名無しさん
2008/01/19(土) 18:29:000066デフォルトの名無しさん
2008/01/19(土) 19:33:18クラスを使えると便利 →やや好き
難解な文法というか落とし穴にハマる →嫌いになる(この辺で多言語に浮気)
テンプレートがわかってくる →再び好きになる
STLに感動する →好きになる
bind1stとかvalarrayに不満がでてくる →再びちょっと嫌いになる
boostがわかってくる →また好きになる
0067デフォルトの名無しさん
2008/01/19(土) 20:03:21→何でもいいので何か自作のライブラリを作りたくなる
boostに追記/修正したくなる
→何かを作る事よりもC++を書くこと自体が楽しくなる
既存のコンパイラに嫌気を射し
C++コンパイラを自分で作りたくなる
→ちょっと飽きてくる
巨大なプログラムを作成中に過去に自分の書いたコードが読めなくなる
→PCを窓から投げ捨てたくなる
0068引っ越してきました
2008/01/19(土) 20:17:46追い出されて来ました。
クラスの中で+演算子を定義したいのですが、
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);
}
やりたいことはわかってもらえるとは思うのですが、
もっと楽にできるよとかもあったら教えてください。
0069デフォルトの名無しさん
2008/01/19(土) 20:23:500070デフォルトの名無しさん
2008/01/19(土) 20:24:06delete[] tmp_moji;
return mojiretsu;
でどう?
0071デフォルトの名無しさん
2008/01/19(土) 20:44:36newしないでMojiretuを定義してそれをreturnすれば?
Effective C++でもnewはするなと書いてあったぞ。
007268
2008/01/19(土) 20:45:00どうもです。
なるほど、コンストラクタを呼び出す、と。
実験の結果、ちゃんと動いています。
(まあ、もとのやつでも動いているようには
見えるのですが)
007368
2008/01/19(土) 20:46:44どうもです。
少々時間ください。初心者のため
理解するのに時間がかかりますので。
0074デフォルトの名無しさん
2008/01/19(土) 20:51:27混乱しそうだし
0075デフォルトの名無しさん
2008/01/19(土) 20:52:05なんぜ+=なのに、moji1がconstなんだ?
Mojiretsu s1("abc"), s2("def");
s1 += s2;
これでs1 == "abcdef"にならないとおかしいだろ。
007668
2008/01/19(土) 20:55:56ごめんなさい。
+=でなく、+です。
007768
2008/01/19(土) 20:58:58やっぱりわかりません。
もう少しヒントください。
あと、Effective C++のどの辺でしょうか。
そのうち読もうと買ってはあります。
007868
2008/01/19(土) 21:00:50とらいすろーきゃっち、でしょうか。
だいぶあとということでお願いします。
007968
2008/01/19(土) 21:07:19どこが分からないかというと、
Mojiretuを定義するには、
(コンストラクタに)文字列(char*)を
渡す必要がありますが、その文字列自体、
strcatした後のものにしなければならず、
どうどうめぐりのようで
よく分からないのです。
勘違い、ご指摘くださいませ。
0080デフォルトの名無しさん
2008/01/19(土) 21:08:26誰が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
0081デフォルトの名無しさん
2008/01/19(土) 21:09:090082デフォルトの名無しさん
2008/01/19(土) 21:12:07と思ったらMoreのほうだった……、22。
operator +よりもoperator +=を実装しろ。
そして、operator +はこうする。
Mojiretsu operator +(const Mojiretsu& lhs, const Mojiretsu& rhs)
{
Mojiretsu tmp(lhs);
return tmp += rhs;
}
008368
2008/01/19(土) 21:16:53どうもです。
実はMoreも持っています。
また実験してみます。
(時間がかかります)
0084デフォルトの名無しさん
2008/01/19(土) 21:22:53008568
2008/01/19(土) 22:00:52ありがとうございました!
動きました!
+=を先に定義するというのは
頭いいですねえ。
0086デフォルトの名無しさん
2008/01/19(土) 22:12:44008768
2008/01/19(土) 22:20:59そういうものなんですね。
>>82
「More」の22の最初のページの一番下に
「単独演算子がfriendである必要はまったくない」と
あり82でもfriendがついてませんが、friendにしないと、
lhsが"rerere"のような場合に私のではコンパイルエラーに
なったのですが、まだ何かおかしいということでしょうか。
0088デフォルトの名無しさん
2008/01/19(土) 22:24:53publicなコピーコンストラクタはあるか。
+=もメンバならやはりpublicになっている?
82のは、private/protectedなメンバに全く触っていないから
friendにする必要がないという仕掛け。
008968
2008/01/19(土) 22:32:41たびたびありがとうございますです。
コピーコンストラクタも+=も+もその他すべての
メンバ関数はpublicになっているのですが。。。
009068
2008/01/19(土) 22:37:36privateメンバを触っていますがそのせいでしょうか。
Mojiretsu operator+(const Mojiretsu& str1, const Mojiretsu& str2) { // +演算子
String tmp_moji(str1.s); //←コンストラクタにはクラスの文字列部を渡してます
tmp_moji += str2;
return tmp_moji;
}
009168
2008/01/19(土) 22:57:13error C2804: binary 'operator +' に引数が多すぎます。
error C2333: 'Mojiretsu::operator +' : 関数宣言のエラーです。関数の本体は無視されます
っていうのも出たため、実験しましたが、
どの+でもエラーになってます。。。
friendつけている限りまったくwarningさえも出ないのですが。
すいません、時間切れです、明日の夕方、また来ます。
0092デフォルトの名無しさん
2008/01/19(土) 23:19:33来なくていいよ
もっと勉強してから来い
0093デフォルトの名無しさん
2008/01/19(土) 23:26:25迷惑です。もう荒らさないで下さい。
009468
2008/01/20(日) 00:23:56自己解決いたしました。
(error C2804でググって英文を読みました。
確かに読んでいる本ではコード上ちゃんと
なっていますがはっきりと言葉では
書いてないんですよねー、、、)
>>88
や、その他の方々、重ね重ねありがとうございました。
大変勉強になりました。
0095デフォルトの名無しさん
2008/01/20(日) 00:48:41とりあえず次回のためには自己解決の意味を覚えとけ。
0096デフォルトの名無しさん
2008/01/20(日) 02:31:030097デフォルトの名無しさん
2008/01/20(日) 09:50:57最初から知っていた俺がいる。
ただ、ADLでしかlookupできないというのは盲点だったと思っている。
0098デフォルトの名無しさん
2008/01/20(日) 11:39:38終わってるスキルtop10にCが入ってる
c++と区別してcなのか、それともc++込みで終わってるのか
0099デフォルトの名無しさん
2008/01/20(日) 12:12:16そいつバカですね。Cが終わってるなら、C++では重過ぎて
実装できない組み込み機器はどうなるのか?
0100デフォルトの名無しさん
2008/01/20(日) 12:31:480101デフォルトの名無しさん
2008/01/20(日) 12:59:280102デフォルトの名無しさん
2008/01/20(日) 18:24:19> c++と区別してcなのか、それともc++込みで終わってるのか
スラドのくだらない雑談はいいから元の記事嫁よ
って元の記事もかなりくだらないな
0103デフォルトの名無しさん
2008/01/20(日) 23:04:17皆さんは、コーディング中にコメントアウトを使うでしょうか?
以前、仲間内でコメントアウトの是非で議論になりました。
私の知人はコメントアウトを使用する派で、私は使用しない派です。
皆さんは、コメントアウトの是非についてどう思うかお聞かせください。
なお、開発はVC++6.0、2003、2005などで行っています。
ちなみに、私がコメントアウトを否定する理由は
1.ソースが汚くなるから。
2.バックアップなら、zipか何かにまとめてプロジェクトごとバックアップしておいた方が良いから。
の二点です。
よろしくお願いします。
0104デフォルトの名無しさん
2008/01/20(日) 23:38:02コーディングスタイルにこだわるスレ
http://pc11.2ch.net/test/read.cgi/tech/1193554741/
0105デフォルトの名無しさん
2008/01/21(月) 06:53:460106デフォルトの名無しさん
2008/01/21(月) 20:38:50http://pc11.2ch.net/test/read.cgi/tech/1071697977/
0107デフォルトの名無しさん
2008/01/22(火) 17:37:570108デフォルトの名無しさん
2008/01/22(火) 17:45:390109デフォルトの名無しさん
2008/01/22(火) 23:33:330110デフォルトの名無しさん
2008/01/23(水) 02:43:19これらをcatch文の中で使っても安全なのでしょうか?
0111デフォルトの名無しさん
2008/01/23(水) 08:49:57標準ができる前に既にI/Oライブラリは存在していて、後方互換性
のためデフォルトではストリームは例外を投げない仕様だと思った。
exceptionメンバー関数を使ってストリームの各種状態を例外ハンドリング
に変えることは可能。
0112111
2008/01/23(水) 08:50:460114デフォルトの名無しさん
2008/01/23(水) 16:24:22そのオブジェクトが CLS クラスのオブジェクトか判定するには
どうすればできますか?
0115デフォルトの名無しさん
2008/01/23(水) 16:28:43typeid演算子
0116デフォルトの名無しさん
2008/01/23(水) 16:34:330117デフォルトの名無しさん
2008/01/23(水) 17:11:05thx
>>116
組込みですよ。
0118デフォルトの名無しさん
2008/01/23(水) 18:01:080119デフォルトの名無しさん
2008/01/23(水) 18:30:52dynamic_cast はキャスト可能な全ての型で判定が成功するけど、
typeid は(& とトップレベルの const 以外は)厳密に型が一致しないとダメ。
どっちの方がいいというのではなくて目的ごとに使い分けることになるから、
>>114 がどっちの判定がやりたいかによるね。
0120デフォルトの名無しさん
2008/01/23(水) 18:40:580121デフォルトの名無しさん
2008/01/23(水) 19:05:22dynamic_castも要らないだろというところまで話を広げたくなるね。
0122デフォルトの名無しさん
2008/01/23(水) 19:28:590123デフォルトの名無しさん
2008/01/23(水) 19:50:25どういう時に使うんだ?
0124デフォルトの名無しさん
2008/01/23(水) 21:03:450125デフォルトの名無しさん
2008/01/23(水) 22:35:54int& &
この表記はC++03では認められていませんが、C++0xではint&と等価なものとして
仕様が改定されることは決定済みなのでしょうか?
0126デフォルトの名無しさん
2008/01/23(水) 22:52:580127デフォルトの名無しさん
2008/01/23(水) 22:53:45&& を素で書くと右辺値参照だったはず。
0128デフォルトの名無しさん
2008/01/23(水) 23:52:55>>127
そうですか。テンプレートパラメータが既に参照の場合、
参照引数を渡すとT& &となりエラーとなるため、これを
回避することだけを目的としてるのかもしれないですね。
type functionを書くのも面倒なので是非改定
してもらいたいです。もしかすると今でもBoostでは便利
なものがあるかもしれませんが。
右辺値参照はC++03では認められていなくて、C++0xでは
正当になる予定ですよね?
0129デフォルトの名無しさん
2008/01/24(木) 00:15:13うろ覚えだからドラフト読んでくり。
0130デフォルトの名無しさん
2008/01/24(木) 00:24:22確認してみます。
0131デフォルトの名無しさん
2008/01/24(木) 00:34:530132デフォルトの名無しさん
2008/01/24(木) 00:47:44テンプレートでこねこねしていると、うっかり参照への参照という型が生まれることがある。
そんなもの、現状ではコンパイルエラーだが、125に書いてある通り0xだと、
Tへの参照への参照型は、単にTへの参照型として扱われるようになる。
0133デフォルトの名無しさん
2008/01/24(木) 01:00:12& && -> &
&& & -> &
&& && -> &&
0134デフォルトの名無しさん
2008/01/24(木) 01:01:32thx うっかり、ってことは積極的に作るものじゃないって事でOK?
0135デフォルトの名無しさん
2008/01/24(木) 01:19:02http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm#References%20to%20References
このあたりかな。あまり理解できなかった。
改定理由はテンプレートパラメータの問題としてだけでなく、
右辺値参照との絡みもあるみたいだ。かな?
0136デフォルトの名無しさん
2008/01/24(木) 01:35:590137デフォルトの名無しさん
2008/01/24(木) 01:39:010138デフォルトの名無しさん
2008/01/24(木) 01:58:45template<typename T1, typename T2, typename T3>
void f(T!&& x, T2&& y, T3&& y);
例えば、こんな関数にboost::refで一部の引数だけ左辺値参照にすることができる。
そんなことできて何が嬉しいって、例えばBoost.BindやBoost.Lambdaの関数呼出。
これは& &→&というより、&& &→&の説明になっているけど。
0139デフォルトの名無しさん
2008/01/24(木) 13:40:10普通に左辺値を引数にすれば左辺値参照として bind されるのでは?
0140デフォルトの名無しさん
2008/01/25(金) 01:22:360141デフォルトの名無しさん
2008/01/25(金) 02:32:531. 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の言うとおりのような気がする。
0142デフォルトの名無しさん
2008/01/25(金) 13:02:290143デフォルトの名無しさん
2008/01/25(金) 13:17:13boost::refはoutパラメータとして使うためにあるんだと思ってる。
0144139
2008/01/25(金) 13:52:28>>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 が完全に解けるというのが現在の提案の骨子だったかと思います.
0145139
2008/01/25(金) 13:54:25名前が付いた右辺値参照は左辺値として扱われるので,
右辺値として渡された 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 に渡される.
}
0146デフォルトの名無しさん
2008/01/25(金) 15:50:00boost::refについて、これ嘘だった。
0147デフォルトの名無しさん
2008/01/25(金) 16:25:54何が左辺値で何が右辺値なんだかもうわけわからん
右辺値で呼ぶってどういうこと?
0148デフォルトの名無しさん
2008/01/25(金) 16:44:11struct identity
{
typedef T type;
};
template <class T>
inline
T&&
forward(typename identity<T>::type&& t)
{
return t;
}
0149デフォルトの名無しさん
2008/01/25(金) 16:49:21f(i); // T = int & として f が specialization される.
T が int & にdeductionされるのって、パラメータが右辺値参照
のときのみのルールですよね?
0150デフォルトの名無しさん
2008/01/25(金) 16:52:33the 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の数字は何を意味してるんですか?
0151デフォルトの名無しさん
2008/01/25(金) 17:25:21例えばcv1 = const, cv2 = volatileなら、
vc12 = const volatileだよという話をしたいがためのもの。
0152デフォルトの名無しさん
2008/01/25(金) 18:57:19なるほど。unionは合成の意味ですね。てっきりキーワードもunionかと
思ってしまいました。
0153デフォルトの名無しさん
2008/01/25(金) 19:59:08正確には>>148さんの書いたとおりです.
>>147
>何が左辺値で何が右辺値なんだかもうわけわからん
戻り値の型が左辺値参照型でない関数の呼び出し構文(の結果)が右辺値で,
それ以外は全て左辺値,という理解である程度通用するかと思います.
>>149
全部把握しているわけではないので推測になりますが,恐らくそうだと思います.
後方互換性の観点から考えても,
パラメタが右辺値参照型以外の場合は従来どおりの deduction になるかと.
0154デフォルトの名無しさん
2008/01/25(金) 21:19:46ある構造体は中にも構造体を保持していて、その構造体は別ファイルで定義してるとか、
ifdefやら二重に定義されてるマクロやらで手動でやろうとするともうワケワカメです
0155デフォルトの名無しさん
2008/01/25(金) 21:46:14The 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みたいですね。
0156デフォルトの名無しさん
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;
……
な感じで各ファイルの先頭が埋め尽くされるようになりました。
皆さん、どのように解決しているのでしょうか?
0157デフォルトの名無しさん
2008/01/25(金) 23:51:26#include "all.h"
とする。
0158デフォルトの名無しさん
2008/01/25(金) 23:53:590159デフォルトの名無しさん
2008/01/26(土) 00:11:45VC++2005の #pragma once を使ってる場合ですら200ファイルほどのプロジェクトでリビルド時間が半減したんだけど。
0160デフォルトの名無しさん
2008/01/26(土) 00:27:07using もヘッダん中ですんのか?
0161デフォルトの名無しさん
2008/01/26(土) 00:29:140162デフォルトの名無しさん
2008/01/26(土) 00:48:04よく分からんけど、
#pragma once
よりも、
#ifndef XXXXXXX
#define XXXXXXX
////
#endif
の方がビルド時間が短くなるの?
0163くお
2008/01/26(土) 00:49:00よろしくお願いします。
0164デフォルトの名無しさん
2008/01/26(土) 00:59:44#ifndef XXXXXXX
#define XXXXXXX
#include "myhoge.h"
#endif XXXXXXX
とやって include 行を読み飛ばす方法。
myhoge.h にアクセスする必要がない、展開後のファイルサイズが小さくなる、等の理由でビルド時間が短くなることが多い。
0165デフォルトの名無しさん
2008/01/26(土) 01:00:160166デフォルトの名無しさん
2008/01/26(土) 01:01:52all.h に含まれるヘッダのどれか一つでも更新されると all.h を含むファイルが全てコンパイルされる罠。
all.h をプリコンパイルヘッダにしたところで防げません。
0167デフォルトの名無しさん
2008/01/26(土) 01:08:250168デフォルトの名無しさん
2008/01/26(土) 01:11:42なるほど。それだとすると、159の
>リコンパイルで半泣きといえば、いろんな本で冗長インクルードガードが嫌われてるのは何でよ?
の理由は、ヘッダファイル使用時にやることが増えるから。かな?
いや、そっちの方が早いってのなら、合理的な理由じゃないとは思うけど
多分159に対する答えは、そんなところだと思う。
0169デフォルトの名無しさん
2008/01/26(土) 01:12:550170デフォルトの名無しさん
2008/01/26(土) 01:39:560クリアは問題ないですか?sizeof(this)は正しく計算されます?
class HOGE
{
int a,b,c;
char str[128];
void init(void)
{
memset( this, 0, sizeof(this) );
};
};
0171デフォルトの名無しさん
2008/01/26(土) 01:41:18やってみりゃいいじゃん
0172デフォルトの名無しさん
2008/01/26(土) 01:44:07テストのクラスで成功しても、他のクラスでは失敗するかもしれないので。
0173デフォルトの名無しさん
2008/01/26(土) 02:03:15コンパイルが通れば、構文的には正しい。
というのは置いといて、
メンバ変数をクリアしたければ、sizeof(*this)とすべき。
そして重要なのは、その方法が使えるのはPOD型だけ。
例えばHOGEに仮想関数を追加すると、動かなくなる。
0174デフォルトの名無しさん
2008/01/26(土) 02:03:420175デフォルトの名無しさん
2008/01/26(土) 03:01:40詳しく有難うございます。納得できました。
>>174
「構文」は間違いでした。>>173のような事を表したかったのですが、
そういう場合は何と呼ぶべきですかね…
0176デフォルトの名無しさん
2008/01/26(土) 03:20:13つか、何がしたいの?
0177デフォルトの名無しさん
2008/01/26(土) 04:53:51現段階では文字列クラスを用意して双方向リンクリストを使って分岐を操作して居るんですが、どうしてもコードが複雑になってしまいます。
もう少し簡単なアルゴリズムや便利な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);
};
0178デフォルトの名無しさん
2008/01/26(土) 05:00:27void 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);
}
0179デフォルトの名無しさん
2008/01/26(土) 05:34:13sizeof(this) ってポインタのサイズだと思われ
sizeof(*this) にしないとだめなんじゃね?
0180179
2008/01/26(土) 05:36:040181110
2008/01/26(土) 06:16:08std::listを使って一本のリストを作って、リストの各要素のオブジェクトを工夫したほうがいいよ。
リストクラス自作するにしても、これはあまりにも酷い。
せめてコンパイルが通りそうなコードを読ませてくれ。
0182デフォルトの名無しさん
2008/01/26(土) 11:09:34そもそも、クラスの初期化を外部から行なってはいけません。
0183156
2008/01/26(土) 11:23:550184デフォルトの名無しさん
2008/01/26(土) 11:48:39そんなばかげたことする香具師いないからレスがつかないんじゃね?
0185デフォルトの名無しさん
2008/01/26(土) 11:54:160186デフォルトの名無しさん
2008/01/26(土) 12:04:47all.hにはすべてのヘッダファイルではなく、外部から提供されたライブラリのヘッダだけ入れておけば
基本的に更新することはないんじゃない? (その場合、all.hというネーミングは不適切だね。)
0187デフォルトの名無しさん
2008/01/26(土) 12:05:500188デフォルトの名無しさん
2008/01/26(土) 12:18:43using しないとコードが汚くなる。
そこらじゅう ns1::ns2::hoge() とか nsN::nsM::hoge() とかばかりになるぞ。
0189デフォルトの名無しさん
2008/01/26(土) 12:21:44耐えろ。
0190デフォルトの名無しさん
2008/01/26(土) 12:22:45おまいはヘッダファイルでも using 使って
迷惑かけるタイプか
0191デフォルトの名無しさん
2008/01/26(土) 12:26:55どっからヘッダファイルで using なんて考えが出てきたんだ?
*.h と *.cpp では書くものが違うのはあたりまえだろうが。常考。
0192デフォルトの名無しさん
2008/01/26(土) 12:32:23名前空間のエイリアス作ればいいだろ。
0193デフォルトの名無しさん
2008/01/26(土) 12:35:08namespace fuga1 = hoge1::hogeA::hogeX;
namespace fuga2 = hoge2::hogeB::hogeY;
namespace fuga3 = hoge3::hogeC::hogeZ;
……
みたいな解決策もある。
0194デフォルトの名無しさん
2008/01/26(土) 12:36:58エイリアス作ろうぜ。
0195デフォルトの名無しさん
2008/01/26(土) 12:40:22例は?
using 指令と違って using 宣言では名前が衝突するとコンパイルすら通りませんが?
0196デフォルトの名無しさん
2008/01/26(土) 12:41:57パッケージ名を接頭辞に持つプロジェクトの方が上手くいってたりする。
0197デフォルトの名無しさん
2008/01/26(土) 12:44:54そりゃ嘘を教えられたな。
確かにエラーになることは多いが、エラーにならない事もある。
==========
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
}
0198デフォルトの名無しさん
2008/01/26(土) 12:48:05これなら普通は namespace の数 < 識別子の数 なので先頭部分は少し短くなる。
ただし、その代わりにコードは少し長くなる。
どっちにしろ先頭が namespace で埋め尽くされるのは変わらないが。
0199デフォルトの名無しさん
2008/01/26(土) 12:54:22ただ、エイリアスは .cpp のグローバルでのみ作るべし。
名前空間内で作っちゃうとまたややこしい問題が生じる。
0200デフォルトの名無しさん
2008/01/26(土) 12:59:57namespace HogeHoge {
using Hoge::Foo;
void Foo();
}
で普通にエラーでたぞ。
0201デフォルトの名無しさん
2008/01/26(土) 13:04:43あらホント。
0202デフォルトの名無しさん
2008/01/26(土) 13:04:57namespace HogeHoge{
namespace Hoge { void Foo(); }
void Bar(){ Hoge::Foo(); } <- HogeHoge::Hoge::Foo
}
別に間違いようはいくらでもある。
0203デフォルトの名無しさん
2008/01/26(土) 13:06:330204デフォルトの名無しさん
2008/01/26(土) 13:08:55これって防ぎようなくね?
どうすんの? これ。
0205デフォルトの名無しさん
2008/01/26(土) 13:11:53::Hoge::Foo() でアクセスできるよ。
0206デフォルトの名無しさん
2008/01/26(土) 13:12:27なるほど・・・。
でも、常日頃から :: から始めないと防げないよな。
0207デフォルトの名無しさん
2008/01/26(土) 13:13:53後から作るという時点で間違いだとは思うが、
開発中に後から導入したライブラリが・・・ということもあるか・・・。
0208デフォルトの名無しさん
2008/01/26(土) 13:17:40namespace Fuga { void Foo(); }
namespace Hoge = Fuga;
namespace HogeHoge {
class Hoge { public: static void Foo(); };
void Bar(){ Hoge::Foo(); } <- HogeHoge::Hoge::Foo();
}
0209デフォルトの名無しさん
2008/01/26(土) 13:22:31酷い話だとグループ全員が自分用の関数を mylibs に入れていた例が...
0210デフォルトの名無しさん
2008/01/26(土) 13:25:140211デフォルトの名無しさん
2008/01/26(土) 13:28:540212デフォルトの名無しさん
2008/01/26(土) 13:32:14グローバルに alias 作るとヘッダが変わったときに突然コンパイルが通らなくなることあるよ。
0213デフォルトの名無しさん
2008/01/26(土) 13:35:49という規約があった
基底クラスのメソッドさえも
Hoge::Foo:Base:Dosomething();
多重継承を多用していたからという事情もあるんだけど
面倒だけど、安全ではある
0214デフォルトの名無しさん
2008/01/26(土) 13:46:38ぐるっと一周してきた感じだな。
0215デフォルトの名無しさん
2008/01/26(土) 14:07:490216デフォルトの名無しさん
2008/01/26(土) 18:53:060217デフォルトの名無しさん
2008/01/26(土) 19:00:540218177
2008/01/26(土) 19:12:06すいません、文字列クラスがcharacterDataではなくDatabaceでした。
>std::listを使って一本のリストを作って
listやmapを使うことも考えたんですが、リスト化した後のタイプの分岐判定のアルゴリズムが思いつかず断念しました。
なのでその辺のアルゴリズムのアドバイスも出してくれると助かります。
>コンパイルが通りそうなコード
コンパイルも通って動作確認もしてあるので正常に動作しているとは思います。
ただ、これだけ乱雑になると可読性に欠けてバグの温床になりそうなのでアイディアを聞きたいと思った次第です。
0219デフォルトの名無しさん
2008/01/27(日) 01:56:06遅レスだけど、
そういう場合は鼻から悪魔がでますか?って聞けばいいよ。
0220デフォルトの名無しさん
2008/01/27(日) 11:37:37namespace
{
namespace ns = long::longlong::longlonglong::ns;
}
void F1()
{
ns::Foo();
}
0221デフォルトの名無しさん
2008/01/27(日) 13:21:55class 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が表示される
}
0222221
2008/01/27(日) 13:22:31>>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 されないのでしょうか?
0223221
2008/01/27(日) 13:54:47のように変数valを定義した場合、valの型にconstは含まれるのでしょうか?
int const& ref;
の場合は、refの型は int const& となりconstは含まれますよね?
0224デフォルトの名無しさん
2008/01/27(日) 15:46:48val の型に const は含まれる。
0225デフォルトの名無しさん
2008/01/27(日) 15:57:41パラメータリストのconst修飾は関数の型としては無視される、
ということからだろうと思われる
たとえばvoid f(int);とvoid f(int const)の型は全く同一になる
f<int const>(j); とすれば 2 が表示されることに保証があるのか
俺は知らない
0226221
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 ともに同じ結果でした。
0227デフォルトの名無しさん
2008/01/27(日) 16:49:54規格でどうか知りたいなら、規格を読むのが一番だ。
0228221
2008/01/27(日) 17:09:22それはvalue functionのパラメータ及び引数のルールであって、
テンプレートのtype parameterのdeductionはまた別の問題のよ
うに思います。もう少し規格を見てみます。
0229221
2008/01/27(日) 17:12:18>>228は撤回します。
確かにそれが理由のような気がします。
そうすると、const int と T を比べると T が intに
deductionされるのも頷けます。
0230デフォルトの名無しさん
2008/01/27(日) 17:14:12>partial specializationが使用 されることは間違いないです
ああそりゃそうか
>これはテンプレートの標準における正しい仕様なのでしょうか?
14.8.2 -3-にあった
0231デフォルトの名無しさん
2008/01/27(日) 17:17:0614.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.
0232デフォルトの名無しさん
2008/01/27(日) 17:18:110233デフォルトの名無しさん
2008/01/27(日) 17:19:04type function とか value function とか、何の方言?
意味がわからない。
0234デフォルトの名無しさん
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 ]
0235デフォルトの名無しさん
2008/01/27(日) 17:24:04まあ明示的に指定する分には違っててもいいんじゃね?
0236221
2008/01/27(日) 17:34:09>>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
すっきりしました。
0237デフォルトの名無しさん
2008/01/27(日) 17:40:020238221
2008/01/27(日) 17:47:45詳しいことは知りませんが、
現段階で標準で規定された言葉ではないと思います。
テンプレートの本に書かれていました。
value functionはいわゆる通常の関数を指します。
パラメータがtype、引数が値。
type functionとは、通常クラステンプレートで
実現されるものらしいです。
パラメータがテンプレートパラメータ、引数がtype。
struct Widget{};
Test<Widget>::Result;
>>221のTestクラステンプレートの場合、Widgetが引数で
type functionの戻り値がTest<Widget>::Resultと考え
ると通常の関数のように関数とみなせるというもだと
理解してます。
0239デフォルトの名無しさん
2008/01/27(日) 18:03:50「テンプレートの本」ってどれだ?
普通に「関数」と「クラステンプレート」って言ったほうがいいと思うよ。
意味の違いを正しく表している呼び名だとは思えないからね。
後者は「(テンプレート)メタ関数」とか呼ばれるもののような気もするなぁ。
0240221
2008/01/27(日) 18:36:02ここでいうtype functionとは
最近の言葉で表せばメタ関数でしょうね。
Boost::mplなどの最近のメタプログラミングで
使われていますが。
本はC++ Template The Complete Guideです。
著者は標準化委員会の現メンバーでもあり
信用できないものではないと思います。
通常の関数と対比して、コンパイル時に型を引数
とする”関数”という概念的に上手い言葉だと感じ
ているので自分はなるほどと思いました。
0241デフォルトの名無しさん
2008/01/27(日) 19:21:38メタ関数でいいならそう言ったほうがいいでしょ。
わざわざ廃れた用語を使い続ける理由もない。
0242デフォルトの名無しさん
2008/01/27(日) 19:32:18別に正式な名前じゃないけど、
type functionってのはそこそこみる表現だから覚えておいてもいいと思うよ
0243デフォルトの名無しさん
2008/01/27(日) 23:07:12別に廃れてるわけではないよ。
概念を表した言葉だから。
0244デフォルトの名無しさん
2008/01/29(火) 11:46:24名前と引数のタイプを持ったメンバ関数を持つときに限りその関数を呼んで処理したい
のですが、C++ で可能でしょうか?
あ、オブジェクトは必ずしも共通のスーパークラスを持たないとします。要はそういう
場合でも仮想関数的なことをしたいというか...
その特定のメソッドをもつ別クラスを作って、それを全てのオブジェクトで多重継承、
というのも考えているのですが、ちょっとダサいかな? と思って。あとソースのないクラス
では無理ですよね(今のところはソースのあるクラスだけでいいんですが)。
そもそもこんなことを考える事自体ナンセンス、と言われるとアレなんですがw
0245デフォルトの名無しさん
2008/01/29(火) 12:35:210246デフォルトの名無しさん
2008/01/29(火) 12:41:290247デフォルトの名無しさん
2008/01/29(火) 12:44:380248デフォルトの名無しさん
2008/01/29(火) 12:52:140249245
2008/01/29(火) 13:41:34自分で書いてみても、やはり通らない。
こんな風に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 )) ;
0250245
2008/01/29(火) 13:42:580251デフォルトの名無しさん
2008/01/29(火) 14:42:17はおかしくないか?
マッチしなかったぞ。
やるなら
template < typename Y > static Yes test(void (Y::*)(void));
か?
でも、これじゃあ関数名の一致の評価はムリだな。
何か仕組みが必要か。
0252デフォルトの名無しさん
2008/01/29(火) 14:42:50{
void hage(){cout << "hage" << endl; }
};
struct Others
{
void fusafusa(){cout << "fusafusa" << endl;}
};
0253デフォルトの名無しさん
2008/01/29(火) 14:43:13struct 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);
}
0254デフォルトの名無しさん
2008/01/29(火) 14:44:52{
BjarneStroustrup b;
call(&b);
Others o;
call(&o);
}
0255デフォルトの名無しさん
2008/01/29(火) 15:02:09{
typedef void HAGE;
void hage() const {cout << "hage" << endl; }
};
こういう風に typedef 定義して(擬似的な名前一致)
template < typename Y > static One test(typename Y::HAGE *);
じゃだめかいな。
0256デフォルトの名無しさん
2008/01/29(火) 15:34:330257デフォルトの名無しさん
2008/01/29(火) 15:45:03struct 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>();
}
0258デフォルトの名無しさん
2008/01/29(火) 15:46:00template <typename T>
struct has_hage
{
・・・・
template < typename Y > static One test(void (Y::*)(HAGE));
・・・・
} ;
0259デフォルトの名無しさん
2008/01/29(火) 17:12:000260デフォルトの名無しさん
2008/01/29(火) 17:20:470261デフォルトの名無しさん
2008/01/29(火) 17:55:27http://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;
}
0262デフォルトの名無しさん
2008/01/29(火) 18:26:26ほんとだね
0263デフォルトの名無しさん
2008/01/29(火) 18:27:59具体的な解決策はありますか?
0264デフォルトの名無しさん
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;
こんな感じで完全にバインドしてしまう方法はないでしょうか?
0265デフォルトの名無しさん
2008/01/29(火) 18:33:14から
2個取り出すときの全組み合わせ
3個
4個
5個(は1通りだけど)
を文字列(stringでもcharでも)として吐き出すプログラムを
書きたいんですがアイディアだけでもいただけないでしょうか?
0266デフォルトの名無しさん
2008/01/29(火) 18:41:20それなんて宿題?
0267デフォルトの名無しさん
2008/01/29(火) 18:44:37今のC++にはない。0xに乞うご期待。
その方法が嫌なら、使える場合が限られるけど継承するか、
template <class T1>
class AInt : public A<T1, int> {};
あとはプリプロセッサマクロで何とかするか。
0268デフォルトの名無しさん
2008/01/29(火) 18:47:21スレチならすいません
0269デフォルトの名無しさん
2008/01/29(火) 19:03:09なにが固定でなにが引数になるか書いてくれないと答えようがないぜ。
0271268
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;
}
0272デフォルトの名無しさん
2008/01/29(火) 19:06:23ここは見ての通り、C++の規格書を暗記している奴が、
C++の文法で、Bjarne Stroustrupがハゲているかどうか、
コンパイル時に判定するスレだ。
ソースコードが実用的かどうかは、どうでもいい奴らなんだよ。
重要なのは規格違反かどうかということだけだ。
まあ、大方のスレ住人もハゲてるんだけどな。
0273デフォルトの名無しさん
2008/01/29(火) 19:07:300274268
2008/01/29(火) 19:08:50thx
俺はケツ毛までフッサフサです。
0275デフォルトの名無しさん
2008/01/29(火) 19:20:28Template aliases for C++
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1406.pdf
のこと?
0276デフォルトの名無しさん
2008/01/29(火) 19:43:27テンプレートじゃ無理なんか?
0277245
2008/01/29(火) 20:05:40お、それだとVC9でもBOOST_STATIC_ASSERTが通った。
でもおかしいな、確か昔、C++ Templatesで読んで、実際に自分で試してみて、
スゲーと感動した記憶があるんだけど。
たしかVC7だったかな。
あとBoostのhas_xxxって、これ関数じゃないんだね。知らなかった。
0278デフォルトの名無しさん
2008/01/29(火) 20:17:41CHttpFile::SendRequestEx() にて、
CInternetException以外の例外が発生するケースが稀にあるようなんですが、原因が特定できず悩んでいます。
そもそもCInternetException* の例外以外がスローされることってあるんでしょうか?
どっかのサイトでは、CFileExceptionもスローされると書いてあったんですが・・・。
どなたか、このような経験が方いらっしゃいましたら御教授下さい。
0279デフォルトの名無しさん
2008/01/29(火) 20:20:170280デフォルトの名無しさん
2008/01/29(火) 20:24:40で、結局、>>244 のやりたいことは可能なのか?
0281デフォルトの名無しさん
2008/01/29(火) 20:26:510282デフォルトの名無しさん
2008/01/29(火) 20:32:210283デフォルトの名無しさん
2008/01/29(火) 20:35:250284デフォルトの名無しさん
2008/01/29(火) 20:35:450285デフォルトの名無しさん
2008/01/29(火) 20:46:26さー?
>>244が静的な多様性でいいのかどうか分からないからなんとも。
しかし動的な多様性がほしいとすると、引っかかることも。
「ポインタで与えられる」、しかし共通のベースクラスがあるわけではないってことは、void *型で渡すんだろうか。
それだと特定のメンバ関数云々よりも、そもそもオブジェクトのクラスの型は何だってことになるし。
動的な多様性がほしい、
しかし、既存のコードはいじりたくないので、共通のベースクラスに純粋仮想関数は使えないというのなら、
例えばBoost.Anyに使われているType Erasureのテクニックが使えるかもしれない。
あの単純すぎるテクニックを使えば、かなり変態的なことができる。
0286デフォルトの名無しさん
2008/01/29(火) 20:51:54変態ということはわかった
0287デフォルトの名無しさん
2008/01/29(火) 22:36:43class 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;
0288デフォルトの名無しさん
2008/01/29(火) 22:49:25俺はそういう時、
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
0289デフォルトの名無しさん
2008/01/29(火) 22:55:38こんなのでどう
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];
0290デフォルトの名無しさん
2008/01/29(火) 22:57:360291デフォルトの名無しさん
2008/01/29(火) 22:57:48static 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つの比較だけでいいべ。
0292デフォルトの名無しさん
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つの比較だけでいいべ。
0293244
2008/01/29(火) 23:09:34なるほど、テンプレートの特殊化を利用って感じですか? こんな風に使えるんですね。
が、しかし、
>>285
>「ポインタで与えられる」、しかし共通のベースクラスがあるわけではないってことは、void *型で渡すんだろうか。
ビンゴでございます。テンプレートの場合変数の型で挙動が変化してるわけですよね。
自分は Objective-C も使うことがあるので今回のような疑問を持ったのですが。
>しかし、既存のコードはいじりたくないので、共通のベースクラスに純粋仮想関数は使えないというのなら、
とりあえず多重継承で共通のベースクラスを足すことをを検討しています。
>例えばBoost.Anyに使われているType Erasureのテクニックが使えるかもしれない。
そうですか、参照してみます。
0294244
2008/01/29(火) 23:15:51でもやっぱ多重継承の方が自然かなあ。
0295287
2008/01/29(火) 23:16:19ありがとうございます。参考にします
>>292
なるほど。確かにsizeof(Base)<=sizeof(Derived)ですもんね
よく考えたらgreater<T1,T2>的なモノを用意して、それを連ねていくだけでよかったんですね
しかし派生クラスの数が増えるたびにmax_sizeの引数増加版を定義するのが面倒・・
可変引数のtemplateがあればなぁ・・・
0296デフォルトの名無しさん
2008/01/29(火) 23:20:40template<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);
};
0297デフォルトの名無しさん
2008/01/29(火) 23:27:59DEFINE_MAX_SIZE(3, 100);
で max_size3〜max_size100 まで定義、みたいなこともできそうだが、
実用的には生成プログラム書いた方が楽だと思う。
0298デフォルトの名無しさん
2008/01/30(水) 14:46:54C++で継続に関するページがあれば教えてください。
0299デフォルトの名無しさん
2008/01/30(水) 15:44:42全くC/C++以外の経験が無いとかいうレベルだとかなり大変だぞ。
0300デフォルトの名無しさん
2008/01/30(水) 16:21:20rubyでcallccを知り、その関連ページで勉強した程度しか知識がありません。
やりたいことは、まさにrubyのcallccで実行できるようなことです。
0301デフォルトの名無しさん
2008/01/30(水) 16:34:55(Cの)setjmp/longjmpは理解してる?
0302298
2008/01/30(水) 16:40:15「なんでも継続」のページ、良さそうですね。
まずここから始めてみます。
setjmp/longjmpは、Unix C上がりなので知ってます。使った記憶は1回しかありませんが…。
0303デフォルトの名無しさん
2008/01/30(水) 18:00:53Boost.Coroutine
Hamigaki C++ Libraries
0304デフォルトの名無しさん
2008/01/31(木) 00:14:390305デフォルトの名無しさん
2008/01/31(木) 00:17:480306デフォルトの名無しさん
2008/01/31(木) 07:01:140307デフォルトの名無しさん
2008/01/31(木) 08:16:400308デフォルトの名無しさん
2008/01/31(木) 14:59:51Boost.MPLのmpl::vector等
0309デフォルトの名無しさん
2008/01/31(木) 18:29:56は?
0310デフォルトの名無しさん
2008/01/31(木) 21:06:00へ?
0311デフォルトの名無しさん
2008/01/31(木) 21:18:01ん?
0312デフォルトの名無しさん
2008/01/31(木) 22:17:13え?
0313デフォルトの名無しさん
2008/01/31(木) 22:18:19ろ?
0314デフォルトの名無しさん
2008/02/01(金) 00:43:26す?
0315デフォルトの名無しさん
2008/02/01(金) 00:49:58け?
0316デフォルトの名無しさん
2008/02/01(金) 01:17:150317デフォルトの名無しさん
2008/02/01(金) 05:30:190318デフォルトの名無しさん
2008/02/01(金) 05:43:56そんなことはないけど、 ruby や python みたいな言語を触ってる人から見て
配列といって当てはまるのは std::vector でしょうね。組み込みの配列はいろいろ
歴史的な問題も残ったままだし。
0319デフォルトの名無しさん
2008/02/01(金) 07:29:58サイズが完全に決まってるなら
巨大でさえなければ、
組み込みの配列を使った方が効率がいい。
0320デフォルトの名無しさん
2008/02/01(金) 07:53:110321デフォルトの名無しさん
2008/02/01(金) 12:08:03配列を扱うならそこら辺の知識もあってほしいな。
0322デフォルトの名無しさん
2008/02/01(金) 14:50:070323デフォルトの名無しさん
2008/02/01(金) 21:09:38規格には書いてないけどな
0324デフォルトの名無しさん
2008/02/01(金) 21:12:530325デフォルトの名無しさん
2008/02/01(金) 21:18:220326デフォルトの名無しさん
2008/02/02(土) 02:37:390327デフォルトの名無しさん
2008/02/02(土) 03:14:27お前らがnewするたび、stroustrupから領域を割り当てられているのに
ちゃんとdeleteしない奴が多いから…。
そろそろstd::bad_allocが飛んでくるぞ。
0328デフォルトの名無しさん
2008/02/02(土) 12:39:36実際のインスタンスはもっとふさふさなの!
バヤには見えないんだよーだバーヤバーヤ!」
0329デフォルトの名無しさん
2008/02/02(土) 13:50:24俺が作ってやる。
0330デフォルトの名無しさん
2008/02/02(土) 21:17:560331デフォルトの名無しさん
2008/02/04(月) 12:00:17頭髪の少い場合、顎髭や胸毛、ギャランドゥなどで補い、最終的な毛量は一定
0332デフォルトの名無しさん
2008/02/04(月) 12:15:26代わりに心臓に毛が生えまくってるとか
0333デフォルトの名無しさん
2008/02/06(水) 04:31:06> C++ explicitly allows an implementation of delete to zero out an lvalue operand
これ訳すと
「C++ は delete の実装が左辺値である対象をゼロにすることを明示的に許している」
ってことだよね?
int* p = new int;
delete p;
delete した時点で p == 0 になるような実装もアリってこと?
規格見てもそんなことしていいなんて記述は見当たらなかった。
それとも、ただの読み違い?
0334デフォルトの名無しさん
2008/02/06(水) 06:32:38auto_ptrあたりなんかはそれを頼りに実装してる
0335デフォルトの名無しさん
2008/02/06(水) 07:40:080336デフォルトの名無しさん
2008/02/06(水) 07:52:370337デフォルトの名無しさん
2008/02/06(水) 08:26:250338デフォルトの名無しさん
2008/02/06(水) 14:36:13みんな普通にMakefile直接書いてるの?
Windows 上にVirtual Machineでlinuxいれてlinuxとwindowsいったりきたりして開発が
以外と便利と思ったのだけど
0339デフォルトの名無しさん
2008/02/06(水) 17:58:160340デフォルトの名無しさん
2008/02/06(水) 18:42:180341デフォルトの名無しさん
2008/02/07(木) 07:38:54boost::scoped_ptr<T> ptr(new T);
Register(ptr.get()); // セマンティックエラーだがコンパイルは通ってしまう
この問題を解決するために、Registerの引数をshared_ptrにしていたのですが、
ポインタを共有するわけではないのに、shared_ptrはオーバースペックではないかと気になりました。
うまい方法はないですか?
0342デフォルトの名無しさん
2008/02/07(木) 10:10:35要するに Register 関数に所有権を移動させたいのよね? なら
void Register(std::auto_ptr<T> p);
にすれば解決するような気がする
0343341
2008/02/07(木) 10:43:54レスthx。
Register(std::auto_ptr<T>(new T));
という書き方ができないのは諦めるしかないですかね。
0344デフォルトの名無しさん
2008/02/07(木) 10:47:24そういう書き方は普通にできるよ?
# もちろん T が何か具体的な型になっているとして
0345341
2008/02/07(木) 12:25:13あれ?確かにコンパイルできますね(VC2008EEで確認)。
auto_ptrのコピーコンストラクタと代入演算子の引数が非const参照なので、
一時オブジェクトは渡せないと思っていました。
http://ml.tietew.jp/cppll/cppll/article/4745
ここにもありますが、なぜなんでしょう?(vcpp 00059148って何?)
0346デフォルトの名無しさん
2008/02/07(木) 12:40:28void f()
{ std::auto_ptr<T> p = func() ; }
こんなこともできるだよ。
別のクラスをひとつ中継させてるだよ。
0347デフォルトの名無しさん
2008/02/07(木) 12:41:26コンストラクタなんだから。
0348デフォルトの名無しさん
2008/02/07(木) 13:18:22auto_ptrのコピーコンストラクタって非constな参照を受け取るよね。
ということは
void Register(std::auto_ptr<T> p);
Register(std::auto_ptr<T>(new T));
みたいな書き方はダメなんじゃないか?
0349341
2008/02/07(木) 13:30:47ああ、戻り値も一時オブジェクトでしたね。
そう思うと一時オブジェクトがコピーできるように作ってあって当然に感じます。
auto_ptr_refというクラスで解決してるわけですね。
>>347
よく読んでください><
どうもありがとうございました。
0350デフォルトの名無しさん
2008/02/07(木) 14:11:18そうだね。
実際、一時オブジェクトから生成するときは
通常のコピーコンストラクタは使われないね。
auto_ptr_ref経由で変換→変換で
最終的には
auto_ptr(auto_ptr_ref<T> rhs) throw()
: ap(rhs.yp) {
}
というコンストラクタで生成される。
0351デフォルトの名無しさん
2008/02/07(木) 19:05:23delete[] ptr;
実際に delete[] する型は違いますが、確保したメモリは全て開放されますか?
0352デフォルトの名無しさん
2008/02/07(木) 19:19:37>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.
ってことだから、未定義動作じゃないかね
0353デフォルトの名無しさん
2008/02/07(木) 19:19:450354デフォルトの名無しさん
2008/02/07(木) 21:36:48http://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のメモリウィンドウの「??」ってどう判定してんのかが分からん。
誰かここら辺知ってる人いたらおせーてくだせい。
0355デフォルトの名無しさん
2008/02/07(木) 21:55:13環境依存ならスレ違い。
0356デフォルトの名無しさん
2008/02/07(木) 22:09:100357デフォルトの名無しさん
2008/02/07(木) 23:04:01向こうの133に的確な答えが書いてあるじゃないか。そういうことができるクラスを作ればいいんだよ。
0358デフォルトの名無しさん
2008/02/07(木) 23:44:530359デフォルトの名無しさん
2008/02/08(金) 13:49:21コンストラクタは、オブジェクトを安全に使うための準備であると考えると、
thisポインタを他のクラスに渡すことは、安全に使うための準備が完了してないオブジェクトのメンバ関数を呼び出す手段を与えることになり、
危険ではないかと思うのですが、この方法は一般的に使われているのでしょうか?
0360デフォルトの名無しさん
2008/02/08(金) 14:08:360362デフォルトの名無しさん
2008/02/08(金) 17:04:33どういうケースで必要なのかいまいちわかりません
0363デフォルトの名無しさん
2008/02/08(金) 17:38:180364デフォルトの名無しさん
2008/02/08(金) 18:10:31依存名.???<....>
依存名->???<....>
のような場合に最初のangle bracketsはless than operatorなのか
templateの始まりなのかをコンパイラに知らせる必要がある。
依存名.template ???<....>
依存名->template ???<....>
0365デフォルトの名無しさん
2008/02/08(金) 18:16:30VCだと警告が出る。しかし便利。よく考えて使う。
0366デフォルトの名無しさん
2008/02/08(金) 18:30:22でも「プログラミング言語C++」中の限定子が必要な例をVC8に
食わせると限定子が無くても通る、というか限定子を付けると
エラーという(w
VS2008 では知らないけど。
0367デフォルトの名無しさん
2008/02/08(金) 19:19:54テンプレートに関してコンパイラベンダー固有の問題
があることは常識。そんなもんは勝手に調べろってこった。
0368デフォルトの名無しさん
2008/02/08(金) 19:21:04同様の目的で使われる typename も同様。
0369デフォルトの名無しさん
2008/02/08(金) 19:27:240370デフォルトの名無しさん
2008/02/08(金) 19:30:400371デフォルトの名無しさん
2008/02/08(金) 19:31:59で埋め尽くされているBoost
0372デフォルトの名無しさん
2008/02/08(金) 19:39:580373デフォルトの名無しさん
2008/02/08(金) 19:40:490375デフォルトの名無しさん
2008/02/08(金) 21:39:020376デフォルトの名無しさん
2008/02/08(金) 23:56:15とでてしまいビルドできません
手動でリンカにd3d9.libを設定しましたが無理でした
どなたか助けて
0377デフォルトの名無しさん
2008/02/09(土) 00:00:15残念、スレ違いですから。
0378376
2008/02/09(土) 00:18:210379デフォルトの名無しさん
2008/02/09(土) 00:19:110380デフォルトの名無しさん
2008/02/09(土) 10:40:290381デフォルトの名無しさん
2008/02/09(土) 11:30:13もしくは、Linux用に書かれた(?)ライブラリをVisual C++で使うための
一般的な手順・方法というのはあるのでしょうか。
任意精度数値計算ライブラリとして
apflot, gmp 等を使えばよいらしいことまでは分かったのですが
インストールの手順で
configure、nmake 等のLinux系の単語が頻出し困惑しています。
こういうものはVisual C++では使えないのでしょうか。
0382デフォルトの名無しさん
2008/02/09(土) 11:36:12http://www.google.co.jp/search?hl=ja&q=GMP+Visual+C%2B%2B&lr=lang_ja
0383381
2008/02/09(土) 12:17:06これが分かっただけでも、よかったです。
お早い返答ありがとうございました。
0384デフォルトの名無しさん
2008/02/09(土) 18:42:110385デフォルトの名無しさん
2008/02/10(日) 17:59:12int* void F() const{ return &i; }
が通らないんだけども、
Fの中じゃ何も変更してないのに、ポインタを返すものにはconst付けられないの?
0386デフォルトの名無しさん
2008/02/10(日) 18:01:32途中の void はなんだ?
あと const 付きの関数はクラスの非 static メンバとしてしか宣言できないよ。
0387デフォルトの名無しさん
2008/02/10(日) 18:14:23struct S{
int i;
int* F() const { return &i; }
};
S Sobj;
Sobj.F();
が通らないんです。
const int* から int*に変換できないとかで。
0388デフォルトの名無しさん
2008/02/10(日) 18:25:23constオブジェクトからメンバ変数を非constで参照できたらまずいだろ。
試してないけど、workaroundは以下。
const int * F() const { return &i; }
int F() const { return i; }
mutable int i;
0389デフォルトの名無しさん
2008/02/10(日) 20:34:44Sobj.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*で初期化することはできないからコンパイルエラー。
0390デフォルトの名無しさん
2008/02/10(日) 20:59:46int* F() { return &i; }
int const* F() const { return &i; }
std::vector::operator []なんかがこういうことをやっている。
0391デフォルトの名無しさん
2008/02/10(日) 21:29:24片方はキャストを駆使してもう片方を呼ぶようにしましょうってフサフサが言ってた。
tp://www.aristeia.com/images/sdm-big.jpg
0392デフォルトの名無しさん
2008/02/10(日) 22:00:160393デフォルトの名無しさん
2008/02/10(日) 22:08:12やっぱBON JOVIに似てるわ
0394デフォルトの名無しさん
2008/02/10(日) 23:12:56つーかすげーな、、、
>>389みたいなことはどうやったら解るの?
コンパイラでも一度書かないと無理かな。
0395デフォルトの名無しさん
2008/02/10(日) 23:14:490396デフォルトの名無しさん
2008/02/10(日) 23:23:10でもその前に絶対>>395だな
0397デフォルトの名無しさん
2008/02/11(月) 00:55:16http://www.google.co.jp/search?q=%22C%2B%2B%E6%A8%99%E6%BA%96%E5%8C%96%E5%A7%94%E5%93%A1%E4%BC%9A%22+%E6%97%A5%E6%9C%AC%E4%BA%BA
入ってるらしいよ。
0398デフォルトの名無しさん
2008/02/11(月) 01:20:31どう動いてるのかを普段から考えてればいいのさ。
1年も続けてれば大体の事は分かるようになる。
0399デフォルトの名無しさん
2008/02/11(月) 01:45:000400デフォルトの名無しさん
2008/02/11(月) 01:46:540401デフォルトの名無しさん
2008/02/11(月) 02:55:480402デフォルトの名無しさん
2008/02/11(月) 11:11:12どの本?
0403デフォルトの名無しさん
2008/02/11(月) 12:38:10確信が持てるレベルまで行くには、やっぱ規格まで手を出さないといけないんじゃない?
0404デフォルトの名無しさん
2008/02/11(月) 13:04:02結構あった(ほとんど洋書)んだけど最近はめっきり無いね。
残念なことだ。
0405デフォルトの名無しさん
2008/02/11(月) 13:05:330406デフォルトの名無しさん
2008/02/11(月) 17:04:50vector<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++じゃないなぁというか、気持ち悪いって思っちゃう。
0407デフォルトの名無しさん
2008/02/11(月) 17:14:42わざわざ BigSizeClass なんて書いてるんだから結論は出てるんだろ?
参照引数に結果を詰めるなんて C++ (98~2003) ではよくあること。
あと、 2 の関数を使って 1 の関数が実装できるから、効率が許すときだけ
1 の方を使うのもアリかもね。
0408デフォルトの名無しさん
2008/02/11(月) 17:14:53type1でいいんじゃない?
コードでパフォーマンスを見積もるなら、
BigSizeClassのコピーコスト、
GetHoge()の呼び出し頻度、
vectorの要素数
くらいないとわからんよ。
0409デフォルトの名無しさん
2008/02/11(月) 18:50:07typedef 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++仕様として合ってるかどうかが
不安で…。
0410デフォルトの名無しさん
2008/02/11(月) 19:17:04継承すること自体には問題ない。
ただし new extest(...) で生成したオブジェクトを test* を使って delete は
できないことに注意。このため private 継承にしてもいいなら、そっちのほうが安全。
あと、その例の構造体名 _test は予約名になるから、素直に struct test にしておくこと。
0411デフォルトの名無しさん
2008/02/11(月) 19:27:45>できないことに注意
??なんで?
例のtest構造体なら仮想デストラクタもいらないし・・・
0412デフォルトの名無しさん
2008/02/11(月) 19:40:375.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."
0413デフォルトの名無しさん
2008/02/11(月) 19:55:19_test に仮想デストラクタ持たせれば済む話だと思う。
0414デフォルトの名無しさん
2008/02/11(月) 20:01:34本当は test が virtual なデストラクタを持ってないのが原因ってことか。
0415デフォルトの名無しさん
2008/02/11(月) 20:09:032. _test を private あるいは protected 継承する
この2通りだな。
というか、構造体にする必要もないと思うのだが。
0416409
2008/02/11(月) 20:11:30test構造体に仮想デストラクタを入れると、newした場合も
_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)というエラーは出なくなりました。
ただ、継承したい構造体が他のC言語ライブラリが提供するものなので、
継承ではなく包含の方向で考えていきたいと思います。
どうもありがとうございました。
0417デフォルトの名無しさん
2008/02/11(月) 20:17:15処理系用の予約語だから、_test じゃなくて test_ にしとけ。
0418デフォルトの名無しさん
2008/02/11(月) 20:20:39包含がアリなら private 継承も考えたほうがいいかもね。
_BLOCK_TYPE_IS_VALID の assert は問題の未定義動作を捕まえて
くれてるのかな?
0419デフォルトの名無しさん
2008/02/11(月) 20:24:12無理に継承しなくても。
0420デフォルトの名無しさん
2008/02/11(月) 20:35:30継承せざるを得ない場合をのぞいては、包含のほうが良いと言ってたな。
0421416
2008/02/11(月) 21:17:01なるほど、了解しました。
>>418
すいません、private継承で動作確認した時に delete (test*)pext; のように
して同様のアサートが出てたんですが、 delete static_cast<test*>(pext);
とすることでコンパイル時チェックがかかるようになりました。
ただ、C言語ライブラリ側で構造体をmalloc/freeで確保/破棄するように
なっていて、継承を用いた場合、クラスと構造体双方のインスタンスの
生存期間の管理が複雑になりそうに思えたこともありましたので…。
_BLOCK_TYPE_IS_VALIDのassertはやはり仮想デストラクタが未定義と
いうことを示しているようです。
>417-420
あらためて、ありがとうございました。
0422デフォルトの名無しさん
2008/02/11(月) 23:17:010423デフォルトの名無しさん
2008/02/11(月) 23:30:24クラス内ならできるな
0424デフォルトの名無しさん
2008/02/11(月) 23:30:520425デフォルトの名無しさん
2008/02/12(火) 08:26:11class extest : public test
{
private:
test* ptr;
...
にしたほうがいいんじゃないか?
0426425
2008/02/12(火) 08:34:14>425
>>409
class extest
{
private:
test* ptr;
...
にしたほうがいいんじゃないか?
0427デフォルトの名無しさん
2008/02/12(火) 08:43:180428デフォルトの名無しさん
2008/02/12(火) 08:58:03んなこたない。
0429デフォルトの名無しさん
2008/02/12(火) 10:41:36protectedメンバーにアクセスする状況もある。
0430デフォルトの名無しさん
2008/02/12(火) 18:40:440431デフォルトの名無しさん
2008/02/12(火) 20:22:260432デフォルトの名無しさん
2008/02/12(火) 23:28:01ちょっと遅レスだけど、俺も前に同じこと悩んだ。
それで考えたのが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;
}
0433デフォルトの名無しさん
2008/02/13(水) 07:09:49よくわからん。詳しい説明きぼん
0434デフォルトの名無しさん
2008/02/13(水) 11:05:340435デフォルトの名無しさん
2008/02/13(水) 11:50:20経緯から。
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()内で作られた要素が破棄されメモリも解放
0436435
2008/02/13(水) 12:07:33非const参照引数だと一時オブジェクトを受け取れなかったりするけど
VC++だとコンパイル通るので↑では気にしてない。
ちゃんとC++するならauto_ptr_refみたいな
proxyを経由させないといけない。
0437デフォルトの名無しさん
2008/02/13(水) 13:06:170438デフォルトの名無しさん
2008/02/13(水) 13:58:210439デフォルトの名無しさん
2008/02/13(水) 14:36:14template <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;
}
0440デフォルトの名無しさん
2008/02/13(水) 15:28:17vectorに限定しない形で書いてもらえると嬉しい・・・
0441デフォルトの名無しさん
2008/02/13(水) 16:41:48それくらい自分で書けよw
0442デフォルトの名無しさん
2008/02/13(水) 17:30:12Mojoっての知らないからお願いしてみたけど、
考えてみたら超簡単だったw
スマン。
ところで、実行してみたんだけど、これどこかバグってない?
f1の戻り受け取りでコピーコンストラクタ動いちゃうのと、
その際、デストラクタ後のインスタンスが参照されるんだけど・・・。
0443デフォルトの名無しさん
2008/02/13(水) 18:25:15explicit TemporaryVector(Vector<T>& v) : v_(&v) {}
で変換するときに、もうゴミになってるポインタを設定
してるとか?
0444デフォルトの名無しさん
2008/02/13(水) 18:31:52マクロでいきなりコンパイル通らなくて、やる気を削がれるんだけど。
みんなどうした?
0445デフォルトの名無しさん
2008/02/13(水) 18:32:44渡せたのか?
0446デフォルトの名無しさん
2008/02/13(水) 18:45:51struct Two { char x[2] ; } ;
One f(int) ;
Two f(...) ;
void v()
{
std::cout << sizeof( f(hoge) ) << std::endl ;
}
こういうやつか?
0447デフォルトの名無しさん
2008/02/13(水) 18:51:49いや、それは戻り値に評価されるから合法だと思うんだ。よくやるよね。
そうではなくて、コンストラクタの呼び出しを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())));
が怒られる。
0448デフォルトの名無しさん
2008/02/13(水) 18:53:35template<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;
}
0449デフォルトの名無しさん
2008/02/13(水) 19:02:37本来ストリームを操作することを想定していない関数の中で
書式を設定してメッセージを出力したいのですが、
copyfmtで書式の情報を退避するのも例外対策などを考えると面倒なので、
次のように書きたいのです。
#ifdef DEBUG
std::ostream(std::cerr.rdbuf()) << "f(x)=" << std::setprecision(6) << f(x) << std::endl;
#endif
0450デフォルトの名無しさん
2008/02/13(水) 19:40:03tight couplingのことでしょ?
(ストリームバッファの共有)
できるよ。
ostream prec6_cerr(cerr.rdbuf());
prec6_cerr.precision(6);
prec6_cerr << "f(x)=" << f(x) << endl;
これでcerrとprec6_cerrは同じバッファを共有するけど
フォーマットはstreambufではなくostreamに設定される
から別個のフォーマット扱えるとオモタ。
0451デフォルトの名無しさん
2008/02/13(水) 21:06:59これって違法なのかねえ。
よく分かんないや。
とりあえず、
sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg())));
を
sizeof((CompileTimeChecker<(expr) != 0>)((ERROR_##msg())));
にすればいけるね。
関数風キャストから C 風キャストに変更しただけだが。
0452デフォルトの名無しさん
2008/02/13(水) 21:19:530453デフォルトの名無しさん
2008/02/13(水) 21:28:29thx。なるほど。
>これって違法なのかねえ
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)
^
まあ、でもよくこんなこと考え付くわ。面白いけど使いどころあるかな。
0454デフォルトの名無しさん
2008/02/13(水) 21:31:12とかいう式と似たようなもんだから、
void でキャストして明示的に値を捨てないと
警告出すコンパイラもある。
0455デフォルトの名無しさん
2008/02/13(水) 21:32:29boostのio_state_savers使うのがオススメ
0456デフォルトの名無しさん
2008/02/13(水) 21:39:45なるほど。
voidへのキャストって値を捨てるという意味になるのか。
void*はよく見るけど、生のvoidってあまり見ない。
しつこくてすまんが、明示的に値を捨てるという使い方も
voidの機能の一つなんですか?
0457デフォルトの名無しさん
2008/02/13(水) 21:44:400458デフォルトの名無しさん
2008/02/13(水) 21:45:04うい。例えば
#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 にキャストすると、そういうことができなくなる。
0459デフォルトの名無しさん
2008/02/13(水) 21:47:38printf の戻り値を void でキャストして捨てないと
コードチェックに引っかかることがあるというアレか。
0460デフォルトの名無しさん
2008/02/13(水) 21:57:12今考えると、
洒落たテクニックの部類に入りますかね。
>>458
確かに、exprがtrueでヌルポインタ定数0を配列へのポインタ
(int(*)[1])0
に変換できると、今の場合は型が一致するから代入できてしまう。
そこで、voidが不完全型でvoid型変数は定義できないし、どんな型
とも代入互換性が無いことを利用してエラーにすると。
ありがとうございました。よく分かりました。
0461デフォルトの名無しさん
2008/02/14(木) 00:36:45そういえば
sprintf(buf,…);
len = strlen(buf);
というコードを書くバカが多いよな。
0462デフォルトの名無しさん
2008/02/14(木) 00:50:38特にprintf系は機能多すぎだし、読むのメンドウで。
0463デフォルトの名無しさん
2008/02/14(木) 01:19:120464デフォルトの名無しさん
2008/02/14(木) 01:31:21どっちにしろC++09で右辺値参照入れば用済みさ。
0465デフォルトの名無しさん
2008/02/14(木) 02:04:22コンパイラの最適化で十分らしく何の効果もなかった
0466デフォルトの名無しさん
2008/02/14(木) 02:13:320467デフォルトの名無しさん
2008/02/14(木) 06:44:55struct 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してるみたいになる。
0468デフォルトの名無しさん
2008/02/14(木) 06:49:540469デフォルトの名無しさん
2008/02/14(木) 08:14:59・ポリモフィズムしたい
・挿入/削除が高頻度
・何種類かのソートが高頻度
理想はboost::ptr_containerを使ったboost::multi_indexだと思うんですが、どうやらありません。
どのコンテナを使うべきだと思いますか?
0470デフォルトの名無しさん
2008/02/14(木) 08:39:39コンテナの具体的な用途に絞れば ptr_container が担当する部分を自分で書くのは
あまり難しくないだろうから、ポインタを要素型にした multi_index かな。
0471デフォルトの名無しさん
2008/02/14(木) 08:42:25std::vectorでじゅうぶんだろ
0472469
2008/02/14(木) 09:46:52>>470
ptr_containerを使えないのは残念ですが、その方法になってしまいますか。
>>471
vectorを使うなら、ptr_vectorを使いたいです。
0473デフォルトの名無しさん
2008/02/14(木) 09:49:14ソートが高頻度という要件で multi_index は要らんだろ。
何種類かのキーによるアクセスが高頻度ということなら欲しくなるけど。
multi_index が要らないなら ptr_list かな。 >470 と同じ理由で std::list で
十分とも言えるそうだけど。
0474469
2008/02/14(木) 10:27:06"何種類かのソート"と書いたのは、std::sortに渡す関数オブジェクトが何種類かあるという意味です(連想配列ならキー)。
std::vectorやstd::listで十分というのは、
ptr_containerを使うよりstdのコンテナを使うメリット(というよりptr_containerのデメリット?)が何かあるんでしょうか?
0475デフォルトの名無しさん
2008/02/14(木) 10:50:43std::sort
だったらランダムアクセスイテレータを持つコンテナに
限定されてしまわないかい?
0476469
2008/02/14(木) 11:00:26std::sortを絶対に使わないとダメというわけではなくて、std::sortを使えるコンテナにstd::sortを使った場合の話です。
listならメンバ関数のsortを使えばいいし、mapなら(複数のキーでアクセスしたいので)multi_indexですね。
0477デフォルトの名無しさん
2008/02/14(木) 11:45:09要するに要素本体はどこか別のところに保持しておいて、それへのアクセス用ポインタをstd::vectorに突っ込んであるというような。
0478デフォルトの名無しさん
2008/02/14(木) 12:46:21どちらを探してるの?
0479デフォルトの名無しさん
2008/02/14(木) 12:46:550480デフォルトの名無しさん
2008/02/14(木) 12:56:560481デフォルトの名無しさん
2008/02/14(木) 13:09:250482デフォルトの名無しさん
2008/02/15(金) 02:47:53size_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;
}
0483デフォルトの名無しさん
2008/02/15(金) 02:49:23wchar_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を一度で済ませる事で速度的に向上が見られたためなのですが、
まだ文字数が増えたときの変換が遅い気がするので
他に速度を早くする方法があれば教えてください。
よろしくお願いします。
0484デフォルトの名無しさん
2008/02/15(金) 03:53:00_TマクロとSTLのstring/wstringを使って、Unicode版とMBCS版を作ればいいんじゃないか?
0485デフォルトの名無しさん
2008/02/15(金) 04:37:260486デフォルトの名無しさん
2008/02/15(金) 05:48:16非const参照の一時オブジェクトで怒られるとかじゃなくて、RVOで?
RVOがあってもv2=v1;には影響ないはずだけど・・・。
0487デフォルトの名無しさん
2008/02/15(金) 05:54:50#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;
}
0488続き
2008/02/15(金) 05:58:32move_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破棄で中身が破棄される。
0489デフォルトの名無しさん
2008/02/15(金) 12:01:58VC++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; } //確認用
};
0490デフォルトの名無しさん
2008/02/15(金) 12:05:56boost.ublas.matrix
とかは対応してるの?
0491483
2008/02/15(金) 12:11:22stringを使っていないのは、
GetWindowTextからSetWindowTextまで型変換をせずに済ませたいためです。
また、Unicode版・MBCS版と2種類作らずに、
1つのプログラムでNT系+9x系と使える方法を考えてます。
0492デフォルトの名無しさん
2008/02/15(金) 12:42:37デストラクタにメモリの解放を任せるため、
それでも vector くらいは使った方がいいよ。
あるいは realloc とか使うのであれば、
自作のコンテナかスマートポインタかを作るか。
vector で受ければ、要素の挿入も自動で出来るからプログラム楽だし。
ただ、メモリを縮小することは基本的にはできないかな。
(resize でメモリ少なくしても、メモリの再確保は行われない)
もう1つバッファ作ってそこにコピーするならいけるけど。
wstring で受けた方が replace メンバ関数があるから便利だけど、
メモリの連続性は多分全てのコンパイラで保証されてるとは思うけど、
ヌルターミネータの扱いがどう実装されてるか
(常にヌルターミネータを付ける実装になっているか、
それとも c_str 実行時にヌルターミネータを付ける実装になっているか)
の問題がよく分からないので、やめといた方が無難。
あと、効率を求めるならまた他の実装もあると思う。
その他の特定の場合にエラーが出るかどうかは、
Replace の中身次第やね。これ以上は何とも言えん。
0493デフォルトの名無しさん
2008/02/15(金) 13:29:54あとシステムのAPIなどはともかく、
内部の加工などで\0終端を前提として書いたり、
前提とする関数を使ったりするのも止めた方がいい。
0494デフォルトの名無しさん
2008/02/15(金) 13:36:24POD 型でも内部に内部へのポインタ持ってたらアレだけど、
それは C でも同じ事だし。
0495デフォルトの名無しさん
2008/02/15(金) 14:39:47分かった上で使ってる人なら良いんだけど・・・。
realloc使った上で例外安全にするのは別に難しくはないけど、
reallocとかmallocとか使ってるようなCっぽいソースは
大体例外安全でない兆候だと思う。
Cで書かれたライブラリを使う(C++ → C方向のみ)とか、
独自アロケータ実装とかなら大丈夫だろうけど。
それに>>482を>>483したらrealloc分が普通にリークするし、
483のnewの後、throwする可能性のある関数呼んだら
同じくnew分がリークする。
>>492がvectorとかスマートポインタ勧めてるのも
そういうことだと思う。
0496デフォルトの名無しさん
2008/02/15(金) 14:44:300497デフォルトの名無しさん
2008/02/15(金) 14:54:04closeさせといてガベージコレクタがあるとか抜かす言語は笑えるな
intは回収できるが巨大なファイルリソースはリークするわけだ
0498デフォルトの名無しさん
2008/02/15(金) 15:06:220499デフォルトの名無しさん
2008/02/15(金) 15:08:34禿げあがる程同意。
C#はusing(o1,o2,...){}があるから多少マシだけど、
forみたいにusing用のスコープ作るから
スコープ違いが混じるとネストして見辛くなる。
どう考えてもc++みたいに対象の変数のスコープでDisposeした方が良いと思う。
javaのtry-finally-closeに至っては論外。
しかもcloseで例外出たらfinally内で潰さないと
try内で発生したより重要な例外が消されるし・・・。
0500デフォルトの名無しさん
2008/02/15(金) 16:33:04そして言語はC++/CLIへと進化するのであった、まる
0501デフォルトの名無しさん
2008/02/15(金) 18:29:14とか
Hoge hoge();
とかと書かせるようにすれば良かったのにね。C# も。
0502デフォルトの名無しさん
2008/02/15(金) 21:28:46比較関数が例外を投げないんだったら、比較の順序ごとに
std::set<Base *, Compare>を用意して挿入関数を注意深く書けばいい。
multisetにすると削除のとき最悪O(N)の時間がかかるから、
比較関数にポインタの比較を入れてsetで扱う。
比較関数が例外を投げる場合、同じ方法だと削除関数が
例外を投げることになって相当扱いにくくなる。
OpenBSDのtree.hみたいのを使って侵入型コンテナにするのが現実解かな。
0503デフォルトの名無しさん
2008/02/15(金) 22:59:54vc8で
// hoge.hpp
namespace
{
class A
{
public:
A() {}
};
}
// main.cpp
#include "hoge.hpp"
int main()
{
A a;
}
でmain.cppからAにアクセスできてしまうけど。
なんか理解がおかしい?
0504デフォルトの名無しさん
2008/02/15(金) 23:00:290505デフォルトの名無しさん
2008/02/15(金) 23:11:19できないってみたけど。
というかmain自体が無名名前空間で定義さてれいてAが見えるってことか?
0506デフォルトの名無しさん
2008/02/15(金) 23:13:10同一ファイルじゃなくて同一コンパイル単位
インクルードしてたら同じコンパイル単位に含まれるよ
0507デフォルトの名無しさん
2008/02/15(金) 23:14:42代わりに.hppの中身全体をその場所にコピペしてみろ。
#includeとはそういうことだろ?
0508デフォルトの名無しさん
2008/02/15(金) 23:15:050509デフォルトの名無しさん
2008/02/15(金) 23:22:06なら無名名前空間って使い道あるの?
これって#includeするヘッダ内の公開したくない部分を隠蔽する為のものかと思ったけどちがうのか。
>>508
http://wisdom.sakura.ne.jp/programming/cpp/cpp38.html
(抜粋)無名名前空間にアクセスできるのは同一ファイルのみです
0510デフォルトの名無しさん
2008/02/15(金) 23:27:38要はstatic変数の代用だ
Cではグローバル変数が他のコンパイル単位とぶつからないようにstatic変数ってものがあったが、
static構造体とかstatic typedefといったものはなかった
C++では無名名前空間がそういった役割を果たす
もちろん従来のstatic変数も残ってはいるが
0511デフォルトの名無しさん
2008/02/15(金) 23:33:16不正確な記事だな。著者に連絡しとくといいよ。
0512デフォルトの名無しさん
2008/02/15(金) 23:38:19コンパイラはプリプロセッサの処理の後に動くから、
そういう風に考えれば同一ファイルのみと考えていいんじゃね
0513デフォルトの名無しさん
2008/02/15(金) 23:43:47a.cppとb.cppがそれぞれコンパイル単位内で使うために
class Foo {
void f();
};
void Foo::f() { ... }
のように定義すると、リンクのときにFoo:f()が衝突してしまう。
typedefや構造体の定義そのものはコンパイル単位内で完結しているから、
Cの場合は関数、変数にstaticを付けるだけで衝突を防げたけど、
C++の場合普通の関数、変数の他にクラスのメンバ関数やstaticメンバ変数があるから、
それらがリンク時に衝突しないように無名名前空間が考案された。
0514デフォルトの名無しさん
2008/02/16(土) 04:10:53「swapで交換」とはまた別?
ぁー理解できんorz
0515デフォルトの名無しさん
2008/02/16(土) 08:53:40それはつまりコンパイル単位のこと。
プリプロセスとコンパイルは分けて考えないと駄目だよ。
複数のファイルを扱うのはプリプロセスとリンク。
コンパイルは(結合、加工後の)単一ファイルしか扱わない。
0516デフォルトの名無しさん
2008/02/16(土) 09:36:29move semanticsの汎用的な実装方法のとして
「デフォルトコンストラクト直後のオブジェクトとswap」がある。
でもauto_ptrみたいにswapでなく、メンバをNULLにするような方法もある。
MOJOはswapで移動させるとか限らない。
・・・って感じじゃない?。俺もMOJO詳しくないけどw
0517デフォルトの名無しさん
2008/02/16(土) 09:41:16○ とは限らない
0518デフォルトの名無しさん
2008/02/16(土) 09:59:32そんなんだから >505 みたいな勘違いするんだよ。
入門用の記事なんだから、読み手がコンパイルとプリプロセスを
分けて考えてるとも期待できないだろうし。
0519デフォルトの名無しさん
2008/02/16(土) 10:14:35その意見は一応理解出来るけど、件のサイトには
http://wisdom.sakura.ne.jp/programming/cpp/
>C++入門の読者はC言語経験者であることを想定しています
とある。加えて、namespaceやtemplateなどより、
c++識別子のスコープ・マクロ定義スコープ・#includeの動作を
理解するのが先だと思う。
0520デフォルトの名無しさん
2008/02/16(土) 10:35:16だから何?「ファイル」と不正確な記述にしておいたほうがいい理由でもあるの?
0521デフォルトの名無しさん
2008/02/16(土) 10:47:33コンパイル単位という専門用語はあまり知られていない。
Cを知っている人の間ではファイルと呼んだ方が通りがいい。
あと、日本語では「〜単位で」が「〜ごとに」という
意味になる場合があって、
0522デフォルトの名無しさん
2008/02/16(土) 10:48:01しかし、C言語経験者を想定してるなら
「不正確だから修正が必要」という程のことでも無いと俺は思った。
その記事はstaticとexternを引き合いに出してるし、
それらは(特にC言語で)ファイルスコープと呼ばれる上に、
モロ翻訳単位のことだから。
0524デフォルトの名無しさん
2008/02/16(土) 11:10:010525デフォルトの名無しさん
2008/02/16(土) 11:14:18あまり知られてないとか、ファイルの方が通りがいいとかどうでもいい。
それ以上は自分のブログででも主張したらいい。
0526デフォルトの名無しさん
2008/02/16(土) 11:14:270527デフォルトの名無しさん
2008/02/16(土) 11:17:240528デフォルトの名無しさん
2008/02/16(土) 11:26:530529デフォルトの名無しさん
2008/02/16(土) 11:31:39っていう、二次成長期の真ん中へんに居る子みたいな言い逃れが来ると思うよ。
0530デフォルトの名無しさん
2008/02/16(土) 11:31:41ブログも2chのレスも大して変わらんよ。
「著者に連絡しとくといい」なんてレスに比べれば
個人的な主張なんてかわいいもんだろ。
というか、「どうでもいい」なんて反論?は止めた方がいいかと。
0531デフォルトの名無しさん
2008/02/16(土) 11:35:48重要だと思う。
おれも100%知ってるわけではないけど。
翻訳単位というのはstandardに従えば必ずしも
ファイルである必要はない。たまたま現存する実装ではそうな
っているものがほとんどであるということに過ぎない。
別にヘッダをローカルファイルではなく、データベース、ネットワーク
経由で何らかのconfigurationで展開してもstandard準拠といえる。
上にも書いてる人がいるけど翻訳単位とはプリプロセス
(マクロ、ヘッダの展開etc)終了後のエンティティを指す。
リンケージの話は翻訳単位に対して行うものだと思っている。
実際このくらいは知ってないと理解が難しくなる本もある。
カーニハンやジョスティスの本にも頻繁に出てくる。
0532デフォルトの名無しさん
2008/02/16(土) 11:39:47もしかして本人なのかもしれないけど。
0533デフォルトの名無しさん
2008/02/16(土) 12:03:38著者のせいにしたければ勝手に連絡すればいい。
別に止めんよ。
0534デフォルトの名無しさん
2008/02/16(土) 12:04:00「問題の無さ」を2chに書き込むのはおかしい、ということ?
俺にはその感性のほうが意味わからないかも。
Xへの突っ込みが変なせいで、X以外の人間に突っ込まれるなんて、よくあることじゃん。
あと、「繰り返し」っていうのは多分、さりげなく「必死だな」って言いたくて書いてるんだと思うけど、
これは単に、「修正が必要だ」っていう意見の子がまず「繰り返し」書き込んでいるから、
それへの反応も複数回になって「繰り返し」になっているだけだろう。
0535デフォルトの名無しさん
2008/02/16(土) 12:08:19「不正確」に対する反論がそんなに不思議?
こちらは一応根拠を示しているつもりなんだが、
それに対し、根拠も書かずに件の説明が間違っている前提なのが、
むしろ俺は不思議に思うんだけど・・・。
0536デフォルトの名無しさん
2008/02/16(土) 12:12:29一人いたのは事実。それを著者が知れば、修正するかもしれないし
>512,533 のように判断して修正しないかもしれない。それは著者の自由。
修正が必要だという主張も不要だという主張も同じぐらいに的はずれ。
0537デフォルトの名無しさん
2008/02/16(土) 12:12:42509が見るサイトを間違えてる気はするよな。
普通のc++入門サイトとか見た方が良いだろうから。
0538デフォルトの名無しさん
2008/02/16(土) 12:12:570539デフォルトの名無しさん
2008/02/16(土) 12:15:34上から目線を楽しみたいのはわかったけど、ちょっと変。
「修正が必要だという主張も不要だという主張も同じぐらいに的はずれ」という箇所から察するに、
この件についてどっちでもない立場がある、という前提で言ってるんだよね?
なのに、「修正が必要だという強弁に反論した」だけで、それを「不要だという意見」に括るのはおかしいよ。
右翼の意見に反論したら即左翼かよ、みたいな。
0540デフォルトの名無しさん
2008/02/16(土) 12:16:03不正確だというのに反論するなら、件の記事の「ファイル」という記述が正確だ
ということになるが、そうじゃないだろ?
ファイルと翻訳単位では確実に意味が違う。
0541デフォルトの名無しさん
2008/02/16(土) 12:19:54今までの、その「不正確」への反論は全部スルーなのは何故?
0542デフォルトの名無しさん
2008/02/16(土) 12:20:14で、連絡したの?
別に、連絡することは絶対に許さんぞとか、俺はスーパーハカーだから
もし連絡したらお前を社会的に抹殺してやるぞとか、そーゆーこと言ってるわけじゃないんだから
さっさとすればいいのに。
0543デフォルトの名無しさん
2008/02/16(土) 12:21:58どっちでもない立場である「著者に連絡しとくといい」を、
「修正が必要だという強弁」に誤読して反論してた人が
「修正が不要だという意見」を持っていた、というお話。
0544デフォルトの名無しさん
2008/02/16(土) 12:22:090545デフォルトの名無しさん
2008/02/16(土) 12:23:59ああなんだ、「お話」の内容を語っていたのか。
やけに現実と異なると思った。
0546デフォルトの名無しさん
2008/02/16(土) 12:27:150547デフォルトの名無しさん
2008/02/16(土) 12:41:11p1
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 のファイルの定義と等しくある必要は無い。
0548デフォルトの名無しさん
2008/02/16(土) 12:45:56不正確w
0549デフォルトの名無しさん
2008/02/16(土) 12:56:16ある単位でまとまったプログラムのテキストのことを「ソースファイル」と呼ぶ。
#include 指令によりインクルードされる全てのヘッダとソースファイルと一緒になったソースファイルのことを「翻訳単位」と呼ぶ。
ただし、プリプロセッサ指令により除外される行は除外する。
0550デフォルトの名無しさん
2008/02/16(土) 13:00:52プログラムのテキストはこの国際規格で「ソースファイル」と呼ばれる単位に保持される。
ひとつのソースファイルと #include を通して取り込まれるヘッダやソースファイルを
すべて併せ、 #if などでスキップされる行を減じて、「翻訳単位」と呼ぶ。
JIS の訳はどうなってんだろ?
0551550
2008/02/16(土) 13:01:180552デフォルトの名無しさん
2008/02/16(土) 13:14:29悪いのは>>503を生み出したゆとり教育。
金毘羅様を疑う前にまず自分を疑え。
比較検討しろ。試行錯誤しろ。すぐ2ちゃんに泣きつくな。
0553デフォルトの名無しさん
2008/02/16(土) 13:22:27俺としては、
・c言語経験者前提
・ファイルスコープという言葉は一般に使われている
から、件の文脈でファイル==翻訳単位と分かる。
503、509はサイトの前提には満たなかっただけ。
つまりサイトの選択ミス。
・c++入門者用のサイト
から、厳密性より分かりやすさ優先することは妥当。
と考える。
大体、cユーザーがFILEと言いつつストリームだったりするのはザラ。
翻訳単位はコンパイラにとってストリーム。
0554デフォルトの名無しさん
2008/02/16(土) 13:24:25不思議だな
0555デフォルトの名無しさん
2008/02/16(土) 13:26:490556553
2008/02/16(土) 13:28:19俺は503が悪いとは思ってない。
学習には積み重ね、つまり順序が必要。
2chにレスして、足りない知識に指摘されたなら、その基礎を学べば良いだけ。
まぁ、試行錯誤が重要なのも間違い無いけどね。
0557デフォルトの名無しさん
2008/02/16(土) 13:40:57C++ の規格では使われなくなってるみたい。やっぱり誤解する人がいたからなんだろうね。
0558469
2008/02/16(土) 13:53:47thx
比較関数にポインタの比較を含める手法があるんですね。参考になります。
いくつかのコンテナを同期させる手間がかかってしまうのは仕方ないですか。
0559デフォルトの名無しさん
2008/02/16(土) 13:54:06http://msdn.microsoft.com/library/ja/vclang/html/_pluslang_scope.asp
>File scope
0560デフォルトの名無しさん
2008/02/16(土) 13:55:090561デフォルトの名無しさん
2008/02/16(土) 14:09:10こちらはどうでしょうか?
http://www.boost.org/doc/html/variant/design.html
>file scope
これも間違った使い方ですよね?
0562デフォルトの名無しさん
2008/02/16(土) 14:16:450563デフォルトの名無しさん
2008/02/16(土) 14:30:28マイクロソフトとBoostも、
ファイルスコープなんて単語使ってもらっちゃ困りますよねw
0564デフォルトの名無しさん
2008/02/16(土) 14:47:28L"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);
};
};
0565デフォルトの名無しさん
2008/02/16(土) 14:49:51検索乙。不正確な記事だから著者に連絡しとくといい。
・・・あ、 MSDN のやつは既出みたいね。
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=99170
0566デフォルトの名無しさん
2008/02/16(土) 14:53:24Cの構造体や配列の初期化と一緒。
そういう初期化ができる型を集成体と言う。
0567デフォルトの名無しさん
2008/02/16(土) 14:54:48そうなんだ。。いままで知らなかった。。
ありがと
0568デフォルトの名無しさん
2008/02/16(土) 15:07:20おお、GJ。
>>557が「やっぱり誤解する人がいたからなんだろうね」
って書いてたから、使わなくなった理由とかを探してた。
それ読んでやっと分かった。
誤解する人がいたから、ではなく、
namespaceが追加されたから、
名前空間スコープ、無名名前空間スコープ(グローバル名前空間)
という上位概念で置き換えたってわけか。
0569デフォルトの名無しさん
2008/02/16(土) 15:14:15無名名前空間スコープとグローバル名前空間スコープとは違うスコープだぞ、いちおう。
0570デフォルトの名無しさん
2008/02/16(土) 15:23:19そうだった。
素で間違えた・・・。
0571デフォルトの名無しさん
2008/02/16(土) 15:33:450572デフォルトの名無しさん
2008/02/16(土) 17:49:580573デフォルトの名無しさん
2008/02/16(土) 21:41:48intは予想通りの動作をしたんですが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になってしまいます。
汎整数拡張とは違うと思うのですが、理由が分かりません。
どうしてこうなるのですか?
0574デフォルトの名無しさん
2008/02/16(土) 21:56:03"%d"してるからだろ常考。%uとかprintfの書式調べろ。
あと0xFFFFFFFFというバイトパターンは符号付整数型だと-1を表すからだろ。
0575573
2008/02/16(土) 22:21:54%dは符号付表現だったのですね。勉強になりました。
0576デフォルトの名無しさん
2008/02/18(月) 03:45:36extern C
してstruct扱いにしてcから(c++でなくて)参照できますか?
0577デフォルトの名無しさん
2008/02/18(月) 07:23:36どちらにしろカプセル化を壊すからやるべきでないことだけは確かだ。
アドレスだけ受け取って、
そのアドレスを渡して処理するヘルパ関数を使うとか。
0578デフォルトの名無しさん
2008/02/18(月) 11:18:27メンバ関数を呼ぶときにthisを積むことができない時点で無理。
0579デフォルトの名無しさん
2008/02/18(月) 11:49:09メンバ変数をアクセスしようってのに、メンバ関数を呼べないから
ダメというのは漏れにはちょっと途中のロジックがわからない・・・
0580576
2008/02/18(月) 12:47:08既存のc++コードのclassにpython.ctypesからアクセスするにはどうするか
知りたかったのです。結構難しいみたいですね。
class hoge
{
public:
char *data
int size
};
のdataとsizeにextern Cからアクセスしたかったのです
0581デフォルトの名無しさん
2008/02/18(月) 12:49:110582デフォルトの名無しさん
2008/02/18(月) 15:01:18C++ではクラスと構造体にはデフォルトのアクセス指定が違う以外に差異は無い、と入門書で読んだのですが、ということはC++では構造体は使わないで良いということでしょうか。
0583デフォルトの名無しさん
2008/02/18(月) 15:07:24typedef struct cordinate{
double x,y,z;
}CORDINATE;
こんなのは構造体で使う。
0584デフォルトの名無しさん
2008/02/18(月) 15:21:130585デフォルトの名無しさん
2008/02/18(月) 15:21:550586デフォルトの名無しさん
2008/02/18(月) 16:59:21C互換の構造体を基本クラスにすれば?
ATL/MFCのCRectとかはそうやってる。
struct C_Struct { };
class CPP_Class : public C_Struct { };
0587デフォルトの名無しさん
2008/02/18(月) 18:07:00それだと、cから参照できなくね?
0588デフォルトの名無しさん
2008/02/18(月) 18:12:59data, sizeというメンバがpublicになっている時点で、
hogeは実質ただの構造体なのでは?
コンストラクタやデストラクタを自分で特に定義していなくて、
メンバ関数もカプセル化じゃなくコードの再利用だけを目的にしているような。
だとすれば、メモリ上ではCの構造体と同じだから直接python.ctypesに渡せばOK。
ちなみに仮想関数を持っている場合はダメ。
>>586の方法なら一応動くけど設計を見直した方がいい。
0589デフォルトの名無しさん
2008/02/18(月) 18:30:45// C
struct C_Struct { };
void c_func(C_Struct*);
// C++
class CPP_Class : public C_Struct { };
CPP_Class hoge;
c_func(&hoge);
>>576がどういう使い方するのか知らんが、C互換の部分だけ見せる事はできるぞ。
0590デフォルトの名無しさん
2008/02/18(月) 19:48:52そんなことしなくても不完全型使えばいいんじゃね。
0591デフォルトの名無しさん
2008/02/19(火) 00:00:40がいたら教えてください。
『第4章 小規模オブジェクトの割り当て』
のP88にチャンクのブロック数をunsigned charに収まる値に
制限した理由について、もしこれをunsigned shortにした
場合、sizeof(unsigned short)よりも小さなサイズのブロック
を割り当てることができなくなることが書かれていますが、
何故だか分かりません。ブロックサイズとブロック数は独立
に管理してるものなのでブロックサイズは1バイトだろうが何バイト
だろうが任意に指定できるはずです。
0592デフォルトの名無しさん
2008/02/19(火) 00:17:55フリーブロックの管理が連結リスト方式だとすると、あるブロックが解放されたとき、そこに次の空きブロックの位置を書き込まなければならない
総ブロック数がunsigned charの最大値以下なら、空きブロックの位置を保持するのに1バイトで足りるが、
総ブロック数がそれより多いなら、空きブロックの位置を保持するにはもっと領域が必要だ
解放されたブロックのサイズが1バイトでは、そこに次の空きブロックの位置を書き込むことはできない
0593デフォルトの名無しさん
2008/02/19(火) 00:55:12{
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 ){ ... };
};
上の方でもでてたけど、こういうコードって何の意味があるの?
0594デフォルトの名無しさん
2008/02/19(火) 01:06:43すごいです。クリアになりました。
確かに未使用ブロックの先頭には次の利用
可能なブロックのインデックスを書き込みます。このインデックスのサイズが
もし2バイト(unsigned short型)なら、ブロックサイズを最低でも2バイト確
保しなければインデックス自体を書き込めないことになりますね。
0595デフォルトの名無しさん
2008/02/19(火) 02:02:37>489 に
//非const参照で一時オブジェクトを受け取る対応。
って書いてあるやん。
俺の理解によると、その意味で A( tmp<struct A> "&" tmp) にしちゃ駄目ぽ。
通常の非 const 参照は一時オブジェクトを受け取れないので代わりに参照の働きをする tmp_ref を自前で導入してる。
tmp_ref<A> は A& を表していて、tmp_ref<A> への変換演算子が A → A& (ただし A が一時オブジェクトでも OK)の変換に相当してると思えば OK?
0596デフォルトの名無しさん
2008/02/19(火) 02:22:49if文で、if (音を感知したら)
do ○○ っていうプログラムを考えているんだけど
その音を感知する部分で何か有効的な物ある?
0597デフォルトの名無しさん
2008/02/19(火) 02:24:57サウンドプログラミング4
http://pc11.2ch.net/test/read.cgi/tech/1185340076/
0598デフォルトの名無しさん
2008/02/19(火) 02:56:06struct bar : foo{ struct foge{}; };
で、barの型からfogeと言う名のstructを導出する時、fooのものを選ぶかbarのものを選ぶかってどうやるんですか?
0599デフォルトの名無しさん
2008/02/19(火) 03:19:050600デフォルトの名無しさん
2008/02/19(火) 03:19:380601デフォルトの名無しさん
2008/02/19(火) 03:22:41foo::foge ← foo のやつ
0602デフォルトの名無しさん
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;
}
};
0603デフォルトの名無しさん
2008/02/19(火) 15:54:42// ■クラス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)'に一致するものが見つからない
うまいこと引き継がれていないみたいで・・・
0604デフォルトの名無しさん
2008/02/19(火) 16:59:310605デフォルトの名無しさん
2008/02/19(火) 17:01:30規格では、派生クラスのデフォルトので上書きされるためと説明されていたはず。
派生クラスでいちいち定義すればいいのだけど、面倒と言われればそれまで。
class ChogeA : public BASECLASS<ChogeA>
{
public:
ChogeA& operator =(unsigned long val32)
{
return BASECLASS<ChogeA>::operator =(val32);
}
};
0606デフォルトの名無しさん
2008/02/19(火) 17:17:33using BASECLASS<ChogeA>::operator =;
って宣言すればおk
あと
return *this;
の部分はダウンキャストが必要な気がする
0607デフォルトの名無しさん
2008/02/19(火) 17:23:22今の場合、コンパイラが暗黙に定義するコピー代入演算子が
派生クラスには存在している。基底クラスとはスコープが
異なるためオーバーロードにはならず、以下のものしか
候補にならないた一致する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=;
};
として可視にすればオーバーロードのセットに入るので
これでも動くかと。
0608602
2008/02/19(火) 20:01:13>>604
>>605
ググりましたところC++入門でその旨記述ありました…お恥ずかしい。
ttp://www-glc.kek.jp/subg/offl/OOjlc/cppgrammer.html
>>606
>>607
凄い!
動作いたしました、感動です。
ちなみにダウンキャストは
return *((T*)(this))としました。
"危険"というのがおっかないですが、基底クラス側で派生クラスのメンバを呼び出したりしたら…ということでしょうか。
0609デフォルトの名無しさん
2008/02/19(火) 20:12:44継承される可能性のあるクラスはコピーコンストラクタや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); // 何が起こるだろう?
}
0610デフォルトの名無しさん
2008/02/19(火) 21:13:58privateにしてしまうと、派生クラスのオブジェクトの正しいコピーと代入
が行えない。(Effective C++ Item12)
せめてprotectedにすべきではないか。
0611デフォルトの名無しさん
2008/02/19(火) 21:19:49最後にキャストしてるから特に危険ではなかったか。
ただ、クラスのデザインとしては。。
やはり、>>605のように基底クラス部分の代入は
基底クラスの代入演算子に行わせて、派生クラス部分
は派生クラスの代入演算子に行わせるのが正等かつ
可読性が良いと個人的には思う。
>>610のメイヤーズのとおり。
0612デフォルトの名無しさん
2008/02/19(火) 21:42:55ポリモーフィズムを前提にするようなクラスに対して、
コピーはまだしも代入をまっとうに定義できるケースは珍しいだろ。
継承されないクラスでもコピーや代入は出来なくて当たり前。
コピーだけが意味を持つ場合はこうする。
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)); }
};
0613デフォルトの名無しさん
2008/02/19(火) 21:50:29漏れは「継承される可能性のある」と、「ポリモーフィズムを前提にする」は
結構違うと思う。違わないようにするべきだという立場もわかるけど。
0614デフォルトの名無しさん
2008/02/19(火) 22:04:30継承される可能性のあるケースとは継承されないケース
もあるわけで、盲目的にコピー、代入を禁止するのは
柔軟性を損ねる。cloneによる深いコピーにしても
実行コストを考えると使いたくないケースは
特に組み込みではよくある。残念ながらnewは小さい
オブジェクト用のアロケータではない。
クラスの使用方法を明確に規定するのが前提だが
そうでないケースでは様々な拡張に応じられるように
しておくべきだと思う。
0615デフォルトの名無しさん
2008/02/19(火) 23:26:05std::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 *);
};
0616デフォルトの名無しさん
2008/02/19(火) 23:39:06流れからして、このレスが明後日のほうへ行ってしまってると感じた。
0617デフォルトの名無しさん
2008/02/20(水) 00:02:460618デフォルトの名無しさん
2008/02/20(水) 00:04:440619デフォルトの名無しさん
2008/02/20(水) 00:07:13Javaじゃん。
つーか、仮想マシンが必要な言語と比較対照にはならんでしょ。
0620デフォルトの名無しさん
2008/02/20(水) 00:08:400621デフォルトの名無しさん
2008/02/20(水) 00:11:060622デフォルトの名無しさん
2008/02/20(水) 00:11:460623デフォルトの名無しさん
2008/02/20(水) 00:12:220624デフォルトの名無しさん
2008/02/20(水) 00:13:17Dもまた同じく。必要のある所ではC++もDもC#/Javaも必要なのは変わりないのです。
0625デフォルトの名無しさん
2008/02/20(水) 00:16:590626デフォルトの名無しさん
2008/02/20(水) 00:17:50関数型言語を使う仕事がしたい。
0627デフォルトの名無しさん
2008/02/20(水) 00:18:520628デフォルトの名無しさん
2008/02/20(水) 00:29:23研究室とかに篭ってシコシコ勉強がしたい。
0629デフォルトの名無しさん
2008/02/20(水) 00:43:03>>618
LINQはSTL並に面白そうだと思っているんだけど、遊んでいる暇がない。
0630デフォルトの名無しさん
2008/02/20(水) 01:15:24こうぶんきなんて解析せんし、無限計算もやらん。遅延評価も
価値を持ちそうにない。なんではやってるんだ。
Dのがいい。
0631デフォルトの名無しさん
2008/02/20(水) 01:33:55コンパイラはLispとかで書かれてることもあるんじゃね?
0632デフォルトの名無しさん
2008/02/20(水) 08:11:20はやってるの?
0633デフォルトの名無しさん
2008/02/20(水) 08:19:55自分の知らない計算パラダイムを知ることによって世界が広がるぞ、マジで
あんたの言ってることは「2次方程式なんて実生活で使わないから
学校で勉強する意味がわからない」とかぬかすガキと似たようなもんだ
>>631
コンパイラはMLとかHaskellの方がやりやすいと思う
0634デフォルトの名無しさん
2008/02/20(水) 08:29:31Windowsでしか走らない時点で興味ない。
0635デフォルトの名無しさん
2008/02/20(水) 08:35:56LinuxはLispと聞いたことがある。
0636デフォルトの名無しさん
2008/02/20(水) 09:00:33> Windowsでしか走らない時点で興味ない。
つMONO
0637デフォルトの名無しさん
2008/02/20(水) 10:26:19実際の話、理数系が苦手だった奴って
日常会話でもアホすぎてむかつくことが多いもんなw
0638デフォルトの名無しさん
2008/02/20(水) 11:08:220639デフォルトの名無しさん
2008/02/20(水) 12:02:080640デフォルトの名無しさん
2008/02/20(水) 12:58:230641デフォルトの名無しさん
2008/02/20(水) 14:49:52昔なら「こういうのはVBで書けば5分でできるんだろうな。VBなんか使い方しらんけどpu」と
思ってたような種類のアプリをサラッと書くのに使ってる。UI 作るのが楽なので重宝してる。
0642デフォルトの名無しさん
2008/02/20(水) 15:37:551.Windows
2.Unix系(Linux含む)
3.組み込み
4.その他
ほとんどが1,2だろうな
0643デフォルトの名無しさん
2008/02/20(水) 15:40:440644デフォルトの名無しさん
2008/02/20(水) 15:48:101.Windows
2.Unix系(Linux含む)
3.組み込み
4.Mac
5.その他
ほとんどが1,2だろうな
0645デフォルトの名無しさん
2008/02/20(水) 16:09:010646デフォルトの名無しさん
2008/02/20(水) 17:28:2068kのコンパイラとかっていう程度でいいじゃん。
どっちもWindowsのツールになるが。
あまり興味ないから、質問取り消すわ。
0647デフォルトの名無しさん
2008/02/20(水) 23:16:420648デフォルトの名無しさん
2008/02/21(木) 00:47:25あ そんなもん?
0649デフォルトの名無しさん
2008/02/21(木) 01:37:01関数宣言と関数中身は一対一とおもってたんですけど、
すでにライブラリに入っている関数中身をプロジェクト内に書くということは
問題ないのでしょうか?
sprintfで書き込むのに必要な配列のサイズを知る方法ってあるのでしょうか?
0650デフォルトの名無しさん
2008/02/21(木) 02:30:15C99だと書込先にヌルを指定すれば、戻り値でわかるようになったんだけど。
VC++の_scprintfのように独自関数を使ったり、
ヌルデバイスをfopenしてfprintfしたりという環境依存の方法か、
標準ライブラリのものを使うのを諦める。
(自分でバッファサイズが分かるものを作ったり、あるいはBoost.Formatのような既製品を使ったり)
0651デフォルトの名無しさん
2008/02/21(木) 21:32:15普通はダメ。
ただし、主に移植性を重視するUNIXのプログラムで、
システムが提供するライブラリ関数と同名の関数を自分で再定義する場合はある。
例えばbasename(3)は標準化される前から多くのUNIXで提供されていて、
しかも挙動が微妙に違っていた。そこで、basenameが無かったり、
あっても標準と違っているOSではbasenameを自前で定義することがある。
そういうコードをリンクできるか、再定義した関数をリンクしたライブラリから
隠すことができるかどうかはリンカ次第。
0652デフォルトの名無しさん
2008/02/21(木) 22:38:37struct X {};
X f();
X&& = f() //OK Xは右辺値参照
X obj;
X&& = obj; //OK Xは左辺値参照
&&があれば、両方で使えますよね。
0653デフォルトの名無しさん
2008/02/21(木) 22:39:24右辺値参照が導入されたら、これまでの左辺値参照の存在意義はどうなりますか?
struct X {};
X f();
X&& x = f() //OK xは右辺値参照
X obj;
X&& x = obj; //OK xは左辺値参照
&&があれば、両方で使えますよね。
0654デフォルトの名無しさん
2008/02/21(木) 22:45:49区別できるからこそ(ry
0655デフォルトの名無しさん
2008/02/21(木) 22:52:32gccが頭よすぎで、全部RVOされます
0656デフォルトの名無しさん
2008/02/21(木) 23:08:09初期化じゃなく代入にすればいいが、
どうしてもコピーコンストラクタが呼ばれて欲しいとなると、
一旦一時変数を作ってそれで受けて、
さらにそれをコピーするしかないのかな。
ただ、RVO に依存して挙動の変わるコードは感心しないので
何らかのチェックのために行うのでなければ、そういうことはしない方がいい。
0657デフォルトの名無しさん
2008/02/21(木) 23:59:44ostringstream foo;
foo << "hoge hoge pu-";
foo.str().c_str(); <- 文字列へのポインタ
0658デフォルトの名無しさん
2008/02/22(金) 00:25:35<new>のoperator new, new[], delete, delete[]は自分で定義してもよい。
ユーザが定義しなければライブラリの実装が使われるって規定がある。
0659デフォルトの名無しさん
2008/02/22(金) 01:01:31呼ぶ側と呼ばれる側の翻訳単位分けてみたらどう?
0660デフォルトの名無しさん
2008/02/22(金) 01:03:500661デフォルトの名無しさん
2008/02/22(金) 01:25:42翻訳単位分ければインライン化は阻害される思うし(多分)、
そしたらRVOも阻害される可能性はあるかと。
リンカが頑張ってたら駄目だろうけどね。
0662デフォルトの名無しさん
2008/02/22(金) 01:30:15move semanticsしたのと、してないのを比べたいんじゃね?
コストが掛かるはずの普通の代入でも、RVO効くとコピーコスト0になるから。
0663デフォルトの名無しさん
2008/02/22(金) 01:44:35多重定義したときに区別を付けるために必要。
0664デフォルトの名無しさん
2008/02/22(金) 01:49:25左辺値参照と右辺値参照の区別があって一番うれしい場面は,
関数の実引数が右辺値なのか左辺値なのかを関数の定義内で
識別できるところです.例示しているコードにおいては,
右辺値参照が一時オブジェクトを束縛できることを除いて
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が阻害されませんか?
0665デフォルトの名無しさん
2008/02/22(金) 01:56:46最適化オフでもRVOするの?
0666デフォルトの名無しさん
2008/02/22(金) 07:34:560667デフォルトの名無しさん
2008/02/22(金) 14:46:39統制を取りたいと思ったとき便利な方法はないだろうか.
どこかの馬鹿が int を throw するなどというバカげたことを
していないということをコンパイル時に保証するのは無理?
プロジェクト全体として std::runtime_error と
std::logic_error から派生させたいくつかのクラスを
投げることを規約としているのだけど,馬鹿が適当な
ものを投げてくるかもしれない.
結局 throw を全部見て回るしかない?
0668デフォルトの名無しさん
2008/02/22(金) 14:50:280669デフォルトの名無しさん
2008/02/22(金) 15:04:03ちょ・・・それわ,無理w
マージ担当者にされてあたふたしてる.
0671デフォルトの名無しさん
2008/02/22(金) 16:09:08っ 例外指定
0672671
2008/02/22(金) 16:10:160673デフォルトの名無しさん
2008/02/22(金) 16:46:20まさに言う通りのことを試したいんです。
-O0でもRVOします。
0674デフォルトの名無しさん
2008/02/22(金) 17:12:190675デフォルトの名無しさん
2008/02/22(金) 18:16:10代入では RVO はきかんぜよ
0676デフォルトの名無しさん
2008/02/22(金) 18:20:070677デフォルトの名無しさん
2008/02/22(金) 18:34:48無理
例外指定しても投げようと思えば何でも投げられる。
unexpected exceptionにはなるが。
0678デフォルトの名無しさん
2008/02/22(金) 19:56:280679デフォルトの名無しさん
2008/02/22(金) 20:03:270680デフォルトの名無しさん
2008/02/22(金) 20:07:240681デフォルトの名無しさん
2008/02/22(金) 20:48:10っていっても自分でも新機能を思いつかないんだけど.
0682デフォルトの名無しさん
2008/02/22(金) 22:07:390683デフォルトの名無しさん
2008/02/22(金) 23:09:15例外用の関数がいくつか追加されてたはず。
例えば catch(...) でも例外が取得できるようになった、とか。
0684デフォルトの名無しさん
2008/02/23(土) 04:31:41そんなもんヌルポインタにアクセスしたり整数オーバーフローさせたり
無茶なキャストでコンパイラ黙らせたりしてるのと同じで、馬鹿が混ざっている
という前提ではどうしようもないもんだろ。
なんで例外だけ取り立ててどうにかしようと思うの?
0685デフォルトの名無しさん
2008/02/23(土) 04:34:570686デフォルトの名無しさん
2008/02/23(土) 04:36:35マージ担当の引き継ぎ事項に書いてあったから.
0687デフォルトの名無しさん
2008/02/23(土) 04:36:36それに従っていない例外を投げている throw 式を
正規表現検索できると思う。
0688デフォルトの名無しさん
2008/02/23(土) 04:41:54int main() {
try {
// main の中身
} catch(const std::runtime_error& e) {
// ここは規約通り
} catch(const std::logic_error& e) {
// ここは規約通り
} catch(...) {
// ここに飛んできたらおかしい
}
}
実際に飛んでこないと分からないがな。
0689デフォルトの名無しさん
2008/02/23(土) 04:46:48そういうことなら throw と catch を検索して様子を見るぐらいで十分でしょ。
それ以上は他の未定義動作や禁じ手と同じで、完全なチェックは無理だと思うよ。
0690デフォルトの名無しさん
2008/02/23(土) 05:12:46const std::auto_ptr<Impl> かな、と思うのですが、
boost::scoped_ptr<Impl> でもよさそうだし、
あんまり意味ないかもしれないけど boost::shared_ptr<Impl> でも。
0691デフォルトの名無しさん
2008/02/23(土) 05:20:45普通は boost::scoped_ptr 。
std::auto_ptr は少し安全性が落ちる。
boost::shared_ptr は冗長。
0692デフォルトの名無しさん
2008/02/23(土) 05:24:36throw を次のようにマクロで置き換える。
#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
これで静的にチェックできるはず。
0693デフォルトの名無しさん
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
0694デフォルトの名無しさん
2008/02/23(土) 05:35:14typeid のところは無視して。
0695デフォルトの名無しさん
2008/02/23(土) 05:44:08<: が [ の代替表現に引っかかる。 < ::std... とスペース一個空けとかないといけない。
throw する型によってエラーが出るのは確認できた。役に立ちそうな予感はする。
ただ、 ~T() throw () {} みたいなのがコンパイルできないのがマズイ感じ。
標準ライブラリの中に throw () とか付いてる可能性を考えると、致命的かも。
0696デフォルトの名無しさん
2008/02/23(土) 08:08:44これみたいに基底クラスを派生クラスのメンバとして
参照しちゃうのってあり?ポリモーフィズムとしても、
メンバとしても、基底クラスにアクセスしたいとき。
0697デフォルトの名無しさん
2008/02/23(土) 10:10:38COW実装したいときはshared_ptrが便利
0698デフォルトの名無しさん
2008/02/23(土) 11:07:20それがない限り、使う気になりません。
それとどんな言語でも最初は仕様がキレイなんですよね。
あのC++だって当初はキレイだったんですよ。
ところが実用的に使われ始めて呪文のような
コードになってしまった。
C#もだんだん仕様が汚くなりつつあると聞いてます。
仕様がすっきりしてる言語なんて全く信用してません。
0699デフォルトの名無しさん
2008/02/23(土) 11:17:42で、C++についてのどういった相談事でしょう?
D言語のことはD言語スレへ、C#のことはC#スレへお願いします
0700デフォルトの名無しさん
2008/02/23(土) 12:22:32例外指定か・・・。なるほど。
throw じゃなくて THROW か何かを使わせることができるならそれが楽なんだが、
その規約を守らない人が出てくると・・・だしなあ。
Java みたいに throws ならいいのに・・・。
0702デフォルトの名無しさん
2008/02/23(土) 14:18:170703デフォルトの名無しさん
2008/02/23(土) 14:25:32ふつーは、derived_class.BaseClass::Greeting()とかって書けばいいから
ポインタ一個分のオーバーヘッドが無駄と言えば無駄だけど、
まー別にいいんじゃねーの。
0704デフォルトの名無しさん
2008/02/23(土) 14:28:24あり得ない解決方法。
別メンバ関数(非仮想)を用意して、
そこで基底クラスの関数へ委譲すべき。
0705デフォルトの名無しさん
2008/02/23(土) 14:30:18あるいは、Derived の Greeting を別関数にするか。
0706デフォルトの名無しさん
2008/02/23(土) 18:18:59C++は初心者です。
C++で、class Signal を定義し、その中に、
string signal_name があったとき、
classを使う側で、
Signal sig1(); とだけすると、
そのsig1がsinanl_nameに自然に入るなんてことは
できないのでしょうか。
コンストラクタの工夫などで。
やはり、Signal sig1("sig1"); として
コンストラクタの中で渡されたstringで
signal_nameを初期化する処理を書いて、
をしなければなりませんか。
同じ sig1 をいう名前を
Signal sig1("sig1");
のように2回書くのがどうもなーと
思ったものですから。
0707デフォルトの名無しさん
2008/02/23(土) 18:29:39コンストラクタの工夫では無理だろう
工夫する余地があるとすればプリプロセッサマクロだが・・・
#define sig1() sig1("sig1")
・・・は無理矢理すぎるか
#define DECLARE_SIGNAL(name) Signal name(#name)
で
DECLARE_SIGNAL(sig1); → Signal sig1("sig1")
に展開させるくらいじゃないかな
0709デフォルトの名無しさん
2008/02/23(土) 18:41:19テンプレートプログラミングの末路を見た。
0710デフォルトの名無しさん
2008/02/23(土) 19:08:18何か変なことをやろうとしているような気がする。
0711デフォルトの名無しさん
2008/02/23(土) 20:28:04コンパイラオプションでヒープをもっと増やせばいいだけ。
0712デフォルトの名無しさん
2008/02/23(土) 20:33:150713デフォルトの名無しさん
2008/02/23(土) 20:36:47http://msdn2.microsoft.com/ja-jp/library/yz7kx3y2.aspx
/Zmコンパイラオプション
0714デフォルトの名無しさん
2008/02/23(土) 21:19:01Zmで解決すれば良いけど
0715709
2008/02/23(土) 21:47:560716709
2008/02/23(土) 21:54:15あきらめるわw
0717デフォルトの名無しさん
2008/02/23(土) 22:11:37大きさの等しい、文字列の配列と整数の配列がそれぞれあるとします。
文字列の配列を、整数の配列の値の順にソートしたいと思います。
std::sort など既存のソートアルゴリズムを使って、これを行ううまい方法はないでしょうか?
例:
std::string a[] = {"aaa", "bbb", "ccc", "ddd"}
int b[] = {7, 1, 5, 4}
の場合、a を "bbb", "ddd", "ccc", "aaa" の順に並び替えたいと言うことです。
実際は文字列だけでなくいろいろな型を使うので、
文字列と整数をメンバとして持つ構造体を作って operator < を定義して std::sort にかける・・・というのは、少し長すぎて気が引けます。
よろしくお願いします。
0718デフォルトの名無しさん
2008/02/23(土) 22:42:09構造体なんかつくらずにpairにしてvectorにでもいれて
比較関数を書いてsortさせるとか。
あるいは、いったんmapに突っ込んで取り出す。
0719デフォルトの名無しさん
2008/02/23(土) 22:59:49pair なら比較関数をかかなくとも、first の方にキーを入れれば、std::sort でソートできますね。ありがとうございました。
0720デフォルトの名無しさん
2008/02/24(日) 00:09:06auto_ptr は不完全型に使っちゃいけないことになってるから、候補からは外れると思うよ。
0721デフォルトの名無しさん
2008/02/24(日) 00:41:30間違った使い方しなければ大丈夫らしいよ
http://ml.tietew.jp/cppll/cppll_novice/article/221
まぁ、scoped_ptrでいいとは思うけど
0722デフォルトの名無しさん
2008/02/24(日) 00:48:03もし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に置換してコンパイラに渡せば一丁あがり。
一度これをやっておけば、コストを気にせず例外仕様をがんがん付けて
実行時の問題をデバッグすることも出来る。
0723デフォルトの名無しさん
2008/02/24(日) 01:14:53たいていの実装ではそうなんだけど、規格はテンプレート引数に不完全型を使った時点で
その効果は未定義としている。
0724723
2008/02/24(日) 01:15:410725デフォルトの名無しさん
2008/02/24(日) 08:40:540726デフォルトの名無しさん
2008/02/24(日) 08:46:27多分 shared_ptr 絡みで追加されたんだと思うが。
実際、許可されてるクラスは
shared_ptr, weak_ptr, enable_shared_from_this の3つだけだ。
0727デフォルトの名無しさん
2008/02/24(日) 08:58:39scoped_ptrや自前auto_ptrなら問題ない。
ただし不完全型をdeleteしたらundefined behaviourなので
(どう考えてもill-formedの間違いだと思うけど)、
自前auto_ptrを作るとしたらboost::checked_deleteを使うべし。
0728デフォルトの名無しさん
2008/02/24(日) 09:45:19しかしその実装を見てもなにやってるのかわからん.
まんなかの (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;
}
0729デフォルトの名無しさん
2008/02/24(日) 09:50:060730デフォルトの名無しさん
2008/02/24(日) 10:02:04使わないと最適化ですっ飛ばされちゃうこともあるのかねぇ.
0731デフォルトの名無しさん
2008/02/24(日) 11:06:20CodeWarrior8 のバグみたい。
0732デフォルトの名無しさん
2008/02/24(日) 11:56:33sizeof(T)? 1: -1
sizeof(T) が 0 になることなんてあるの?
0733デフォルトの名無しさん
2008/02/24(日) 12:00:070734デフォルトの名無しさん
2008/02/24(日) 13:18:23printf("%d", sizeof(Hoge));
→1
エーッ
0735デフォルトの名無しさん
2008/02/24(日) 13:24:05例えば
Hoge hoge[2];
&hoge[1] - &hoge[0] == 0
とかじゃまずい
0736デフォルトの名無しさん
2008/02/24(日) 13:25:01不完全型とはvoidとか
class Widget;
のこと?
だったらsizeof(void) sizeof(Widget)はコンパイルエラーになるんだけど。
0737デフォルトの名無しさん
2008/02/24(日) 13:29:51不完全型にはsizeof演算子は適用してはいけないと書かれてるんだが。
0738デフォルトの名無しさん
2008/02/24(日) 13:33:53コンパイルエラーになってほしいんだからそれでおk
0739デフォルトの名無しさん
2008/02/24(日) 14:02:320740デフォルトの名無しさん
2008/02/24(日) 14:08:00それを利用してコンパイルエラーにさせるから、"checked_" だろ
0741デフォルトの名無しさん
2008/02/24(日) 14:08:590742デフォルトの名無しさん
2008/02/24(日) 14:09:260743デフォルトの名無しさん
2008/02/24(日) 14:21:10最小のフットプリントで不完全型を渡せる scoped_ptr の代替はないんだな。
unique_ptr でも不完全型を許可してほしいなぁ。 checked_delete 相当の
default_delete とか使うんだから、問題になることはないはず。
0744デフォルトの名無しさん
2008/02/24(日) 14:39:41(A diagnostic is required if T is an incomplete type.) って書いてあるな。
デリータがテンプレートパラメータになってるから
デリータを自分で指定すれば好きに出来そうではある。
0745デフォルトの名無しさん
2008/02/24(日) 14:45:33そこまで書いておきながら、 unique_ptr に不完全型を許可する記述が無いのは
おかしいな。もしかして、書き漏らしてるだけ?
0746デフォルトの名無しさん
2008/02/24(日) 14:46:54>>740
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
仮に、sizeof(T)が0に評価されたときに
配列が-1という要素を持つことが許されないという理由でコンパイルエラー
にするという意図ならわかるが、>>733が言ってるとおりだとすると単に
不完全型だということなら、そもそもsizeof(T)自体がエラーの原因になるだろ。
だが、規格ではsizeof(不完全型)は許されていない。
規格に従えば、不完全型Tに対してsizeof(T)が0になることはない。
>>739
それなら納得
0747デフォルトの名無しさん
2008/02/24(日) 15:00:260748デフォルトの名無しさん
2008/02/24(日) 15:05:54BOOST_WORKAROUND なんてもんは必要ないな。
0749デフォルトの名無しさん
2008/02/24(日) 15:09:35デリータ次第だから default_delete に記述があれば十分だろう。
というか、これは不完全型は許可してないという記述じゃないのか?
いや、まあ挙動が定義されているからある意味許可はされているのか。
0750デフォルトの名無しさん
2008/02/24(日) 15:32:45default_delete については不完全型を許可している(コンパイルエラーになると
規定している)ように読めるけど、それは unique_ptr に不完全型を渡した場合の
動作について何か言っていることにはならないでしょ。 default_delete 以外も
使えるんだし。
0751デフォルトの名無しさん
2008/02/24(日) 15:37:22規定できるわけないとまではいわんが
規定が無いのならユーザが自由にできるってことでしょう。
0752デフォルトの名無しさん
2008/02/24(日) 15:58:15個別の規定が無い場合は >>723-724 のとおり未定義ってことになってしまう。
0753デフォルトの名無しさん
2008/02/24(日) 16:25:59733は不完全型の場合にsizeof(T)が0になることがあるって意味だろ?
同じこと言ってると思うぞ
0754デフォルトの名無しさん
2008/02/24(日) 16:43:49エラーにならず 0 になる処理系があって、その対策なんだろうという話だな。
0755デフォルトの名無しさん
2008/02/24(日) 16:43:49どのコンパイラ?
0756デフォルトの名無しさん
2008/02/24(日) 16:45:10ああ、あああ、ああ、そうか。
じゃあ未定義なんだろうな。
0757デフォルトの名無しさん
2008/02/24(日) 16:45:31それなら>>739の言い方が正しい。
>>733だと、まるで不完全型Tに対しては常にsizeof(T)が0になると誤解される。
0758デフォルトの名無しさん
2008/02/24(日) 16:55:40http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#762
書き漏らしてるだけみたい。
0759デフォルトの名無しさん
2008/02/24(日) 17:18:01俺に言われても知らない。733に聞いてくれ
>>757
誤解を招くってのは分かる
けど>>732に対して>>733なら「なることがある」だろ
# というか733みたいなおそらく一例を挙げただけの即答にツッコミ杉w
このスレに居るなら「すべきである」「しなければならない」みたいな違いに敏感だろうに・・・
0760デフォルトの名無しさん
2008/02/24(日) 20:26:130761デフォルトの名無しさん
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は等価という理解でいい?
0762デフォルトの名無しさん
2008/02/24(日) 21:05:45元のオブジェクトがどうなってもいいっていうのが非 const 右辺値参照でしょ。
2がコンパイルできるようだと右辺値参照の意味がないような気がする。
コンパイルエラーになるんじゃね?
0763デフォルトの名無しさん
2008/02/24(日) 21:14:41struct a : base<0>{};
struct b : base<1>{};
struct c : base<2>{};
struct d : base<3>{};
......
何らかの型がbase<*>を継承している場合、その何らかの型とbaseの情報だけで
baseに指定されたテンプレートパラメータを取得する方法はありませんか?
0764デフォルトの名無しさん
2008/02/24(日) 21:18:360765デフォルトの名無しさん
2008/02/24(日) 21:18:51これが使えるかどうか自信がないけど。
template<int n>
void f(base<n> const&)
{
}
0766デフォルトの名無しさん
2008/02/24(日) 21:40:14intならenum
typeならtypedef
で保存
0767デフォルトの名無しさん
2008/02/24(日) 22:02:46draftに以下の記述があるんだけど、これはどういう意味?
struct A {};
A a;
A&& ar = a;
The expression ar is an lvalue of Type A.
0768デフォルトの名無しさん
2008/02/24(日) 22:03:250769デフォルトの名無しさん
2008/02/24(日) 22:13:54「 ar という式は型 A の左辺値である。」
・・・読んだまんまなんだが、こんな答えでいいのか?
0770デフォルトの名無しさん
2008/02/24(日) 22:26:02draftにそうあるなら左辺値になるんだろうな。
それを>>761の(2)と(3)でオーバーロードされたfに渡したら
左辺値扱いなので(3)の方が選ばれる・・・とか? 俺も仕様知らないけど
0771デフォルトの名無しさん
2008/02/24(日) 22:34:57説明不足だった。
�A�Bのそれぞれの関数f()は、オーバーロードというつもりで
書いたわけじゃなくて渡す引数が左辺値なら、f()をどっちで定義しても
同義じゃないかと思った。
�A
void f(X&& r);
X x;
f(x); //この場合(X&& r = x)は、rは左辺値参照。
�B
void f(X& r);
X x;
f(x);
0772デフォルトの名無しさん
2008/02/24(日) 22:49:502が通るんなら右辺値参照受け取る関数なんて恐ろしくて作れない。
0773デフォルトの名無しさん
2008/02/24(日) 22:55:53�Aはとおるだろ。で、左辺値参照になるだけじゃねーの?
0774770
2008/02/24(日) 22:59:32説明不足なのはむしろ俺かwすまん
オーバーロードの意味じゃないのは分かってる
で、よく仕様知らないと言いつつ770で想定したのは↓
A a;
A&& ar = a;
f(ar); //arは左辺値扱い(?)なのでオーバーロードがあったら f(A&); の方が優先的に呼ばれるかも
で、arについての話だけ。
で、本題だけど、f(A());のケースだとf(A&&)しか呼べないだろうけど
引数が左辺値ならf()はどっちでも同義だと思う。
0775770
2008/02/24(日) 23:00:390776デフォルトの名無しさん
2008/02/24(日) 23:05:58同じ認識になりますた。
で、オーバーロードの場合だと、左辺値引数を渡したら
左辺値参照を好むから void f(X&); が呼ばれるはず。
0777770
2008/02/24(日) 23:06:56もしコンパイルエラーにならなくても、
左辺値がオーバーロードでf(A&);に行くなら心配無いよな?
両方書いて、少なくともf(A&&)の方は「壊して良い」ってことになるから
0778772
2008/02/24(日) 23:32:57右辺値参照引数に左辺値が渡せないと、 unique_ptr みたいに移動だけを行うような
モノが作れないな。
しかし「左辺値参照になる」ってのは解せないな。受け取った側では実引数が
左辺値か右辺値かによらず、扱いは同じ(式中の仮引数の型は左辺値参照)だろ。
0779デフォルトの名無しさん
2008/02/24(日) 23:38:460780デフォルトの名無しさん
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
といった感じにしたいのですが……。
0781デフォルトの名無しさん
2008/02/25(月) 07:18:06そんな判別はできなさそうだなぁ。存在すらしてなければエラーになるし。
public 継承した上で、継承された名前が派生クラスのメンバと区別できるような
点が思い当たらないし。
なんでそんなことしたいのか、目的を言ってもらえればもうちょっと別の道が
ありそうな気はするんだけど
0782デフォルトの名無しさん
2008/02/25(月) 20:50:21右辺値参照引数に左辺値を普通に渡すことはできない。
明示的に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のように右辺値参照をとる非テンプレート関数に左辺値を渡せば単にエラーになる。
0783デフォルトの名無しさん
2008/02/25(月) 21:07:27右辺値参照を取る非テンプレート関数に
キャストなしで左辺値を渡せると思いますよ
0784デフォルトの名無しさん
2008/02/25(月) 22:32:42draftには
struct A {};
A a;
A&& ar = a;
これは可能ということになってる。独立右辺値参照は
左辺値で初期化可能で関数渡しはNGということは
右辺値参照に関しては、これまでの考えが通用せず
”右辺値参照パラメータの関数の引数渡しは初期化の
セマンティクスとは異なる”
ということになるの?
0785デフォルトの名無しさん
2008/02/25(月) 22:36:20>引数が左辺値の参照渡しに「なる」のは関数テンプレートだけの特殊なルール>。 例えば上のmoveに左辺値xを渡すと、TとT&&はともにX&になってしまう。
これは、move(x)がmove<X&>(X&&& x)となり、&&&は&となるというルールだよな?
0786デフォルトの名無しさん
2008/02/25(月) 22:37:55static_cast とか std::move を使うのは overload の解決を制御するためだと思う。
0788デフォルトの名無しさん
2008/02/25(月) 22:59:40ものすごく細かい話になりますけれど, N2521 読む限りでは
>>784のような例だと右辺値参照も左辺値参照も
全く同じ初期化の規則が適用されるように思われるので,
lvalue-to-rvalue conversion は適用されないんじゃないですかね?
lvalue-to-rvalue conversion があるので,右辺値で初期化できて
左辺値で初期化できないのは不自然に感じられるという意味なら
その通りだと思いますけれど.
0789デフォルトの名無しさん
2008/02/25(月) 23:02:20void f(A&& rv);
A a;
f(a);
の場合、引数渡しでコピーは発生せずに rv は a を左辺値
として扱える(rvはaの別名)ということでOK?
0790デフォルトの名無しさん
2008/02/25(月) 23:05:24OK
0791デフォルトの名無しさん
2008/02/25(月) 23:20:35void 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)) を行う必要がある。
これが正しいのかな?
0792789=791
2008/02/25(月) 23:23:57>>788を見て、>>789はNGかなと思ったんだけど、やっぱ正しいのかな?
それなら、>>791の内容は間違いで
f(static_cast<A&&>(a)) も f(std::move(a)) も必要ないな。
0793788=790
2008/02/25(月) 23:27:35>もし�@が無く�Aだけだった場合は
f(a) はエラーにはならないということでよいと思います.
>>792
788で本筋とあまり関係ないことを書いて混乱させたみたいですいません.
>>789は適切という解釈でよいと思います.
0794デフォルトの名無しさん
2008/02/25(月) 23:29:41新規格が出たらまた本をたくさん出すんだろうな。
出たら欲しいもの
超簡単な初心者本
The C++ Standard Library (second edition) by ジョスティス
Effective C++ (fourth edition) by メイヤーズ
Effective STL (second edition) by メイヤーズ
0795デフォルトの名無しさん
2008/02/25(月) 23:31:180796デフォルトの名無しさん
2008/02/25(月) 23:31:34いえ、ありがとうございます。
0797デフォルトの名無しさん
2008/02/25(月) 23:31:430798デフォルトの名無しさん
2008/02/25(月) 23:38:45追記
A a;
A&& ar = a;
が正しくて、
void f(A&&);
f(a);
が正しくないとなると
”関数の引数渡しのセマンティクスは初期化のセマンティクスと同じである”
というこれまでの概念が崩れてしまうもんね。ちょっと安心した。
0799デフォルトの名無しさん
2008/02/25(月) 23:41:07それは正直もういい。Singletonなんて考えすぎだろ。
0800デフォルトの名無しさん
2008/02/25(月) 23:42:44あれは考えすぎ
0801デフォルトの名無しさん
2008/02/25(月) 23:43:10なら欲しい。
0802デフォルトの名無しさん
2008/02/25(月) 23:47:08という実験結果もWebに載ってたな。Efficient C++の
シングルスレッド版は試したが確かに速かった。バグがあって
ちと苦労したが。
0803780
2008/02/25(月) 23:47:24理由は、
「ファクトリー関数を使用すると決めたけれども、派生クラスで関数の実装を強制できないと不安」
ということです。
#実際にはファクトリー関数みたいなものですが。
派生クラスを作成したときに必ずどこかでミスりそうなので、もしトラップする方法があったら
予防線を張っておこうかと考えました。
0804デフォルトの名無しさん
2008/02/25(月) 23:52:21ちょっと出来るかどうか試してくる
0805デフォルトの名無しさん
2008/02/25(月) 23:55:49風呂入ってていい?
0806デフォルトの名無しさん
2008/02/25(月) 23:56:320807804
2008/02/25(月) 23:57:38runtime 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 が要ったりしますか?
0809デフォルトの名無しさん
2008/02/26(火) 00:32:210810804
2008/02/26(火) 00:39:50考えてみましたけれど, 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;
}
0811デフォルトの名無しさん
2008/02/26(火) 00:45:47{private: //←追加
static void a() {}
static void ab() {}
};
struct B : public A { static void ab() {} };
でなんか問題アルの?
0812780
2008/02/26(火) 01:05:48手動で関数へのアドレスを確認するのは面倒な気が……
>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);
ちなみに、このコードに興味ある人います?いるんでしたらフロ入った後に解説書きますけど。
0813デフォルトの名無しさん
2008/02/26(火) 02:07:33static voidなa,abは要するに仮想関数なわけでしょ?
で、オーバーライド必須にしたい、みたいな。
それのテンプレート版、という話と理解したけど、
ならNVIイディオム使えば終わる話じゃねーの?
0814780
2008/02/26(火) 02:16:16「ファクトリー関数を使用すると決めたけれども、派生クラスで関数の実装を強制できないと不安」
ということですね。struct Bからさらに派生する場合も対応できるようにしたいです。
あとstaticメンバ関数は仮想にできないのでNVIはムリですね。
0815デフォルトの名無しさん
2008/02/26(火) 07:09:37解説希望。
0816デフォルトの名無しさん
2008/02/26(火) 07:22:34正直どういう風に使いたいのかよく分からん。
どういう風な事がやりたいのかとりあえずコード書いてくれ。
コンパイル通らなくてもいいから。
0817デフォルトの名無しさん
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で終わる
}
0818デフォルトの名無しさん
2008/02/26(火) 18:13:360819デフォルトの名無しさん
2008/02/26(火) 18:19:13環境が判らんから何とも言えんが、恐らくは>818。
しかし、何でまたそんな小汚いコードを書いているんだ?
普通にpDst[900] = pSrc[3]と書けばいいものを。
0820デフォルトの名無しさん
2008/02/26(火) 18:20:55そこだけならキャッシュのヒット率だと思うけど…
LinuxでIntelのx86使ってるならVTuneがタダで使えるよ
0821デフォルトの名無しさん
2008/02/26(火) 18:55:21そんなにメモリ確保してあるの?
確保してるとしても、ページフォールト起こしそう。
キャッシュよりそっちのが問題かもしれない。
0822デフォルトの名無しさん
2008/02/26(火) 19:23:41メモリのヒット率ですか・・・
そうだとするとここから先の高速化は難しそうですね・・・
ちなみに環境は以下の通りです。
Intel Core Duo T2500
メモリ1GByte
WindowsXP
VisualC++6.0
>>821
>1200 * 1200000 = 1440000000 だけど、
>そんなにメモリ確保してあるの?
ごめんなさい間違っていました。
1200000ではなく、300000です。
メモリは物理メモリ内に確保できています。
0823805
2008/02/26(火) 20:26:040824デフォルトの名無しさん
2008/02/26(火) 20:28:39デンマーク・オーフス生まれのコンピュータ科学者。
0825デフォルトの名無しさん
2008/02/26(火) 20:38:03thx
デンマークか。C++はアメリカ発信じゃないのがいい。
0826デフォルトの名無しさん
2008/02/26(火) 20:47:460827デフォルトの名無しさん
2008/02/26(火) 20:53:330828デフォルトの名無しさん
2008/02/26(火) 21:24:09ファクトリーを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();
};
0829デフォルトの名無しさん
2008/02/26(火) 21:39:06sizeof(空の構造体) = 1;
なぜ0バイトでなく、1バイトになるんでしょうか?
0830デフォルトの名無しさん
2008/02/26(火) 21:52:53サイズが0だと&kara[0] == &kara[3]とかになっちまってまずい。
0831デフォルトの名無しさん
2008/02/26(火) 21:55:41複数のオブジェクトを作ったときにオブジェクトして何らかのサイズを持って
存在していないとuniqueなオブジェクとしてトアドレスが決まらない。
詳しくはInseide The C++ Object Modelに載ってる。
0832デフォルトの名無しさん
2008/02/27(水) 03:03:34一行が助長に長くなってしまって耐えられません。
0833デフォルトの名無しさん
2008/02/27(水) 03:43:250834デフォルトの名無しさん
2008/02/27(水) 03:50:37typedefを程よく使うしかないね。「程よく」ってのがまぁ、人それぞれなんだけど。
typedef std::vector<MyClass>::const_iterator Iter;
for (Iter i = vec.begin(); i != vec.end(); ++i) {
なんてのは、結構やる人多いはず。
Iterがこれ以降出てこない場合、このtypedefは全体としては「短縮」にも「簡略」にも
なっていないわけだけど、それでも「forの行を短く見せたい」というだけの理由で、俺はよくこう書いてる。
もちろん人によっては、「程よく」の範囲を超えた、余計な足踏みみたいに感じるのだろうけどね。
> 助長に長くなってしまって
このレス書き込む前にリロードしたらもう突っ込まれていたので、突っ込むのやめるw
0835デフォルトの名無しさん
2008/02/27(水) 04:12:490836デフォルトの名無しさん
2008/02/27(水) 06:04:480837デフォルトの名無しさん
2008/02/27(水) 07:33:06それはさておき、1行の長さを抑えるためにもインデントは4カラムにするのが定着した私。
>834みたいなことをすると、同じブロック内で別のイテレータ使いたくなるときに困ると思う。
0838デフォルトの名無しさん
2008/02/27(水) 09:13:290839デフォルトの名無しさん
2008/02/27(水) 10:47:03#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;
}
0840デフォルトの名無しさん
2008/02/27(水) 12:44:210841デフォルトの名無しさん
2008/02/27(水) 12:53:36間違った
i != v.end()
0842デフォルトの名無しさん
2008/02/27(水) 14:03:58C++0xのSTLには採用されるのか?
0843デフォルトの名無しさん
2008/02/27(水) 14:09:07禿が生きてる限り、標準ライブラリにプリプロセッサ使ったブツは追加されないんじゃね。
必要だってことになったら、言語に組み込む方法に持っていかれるだろ。
0844デフォルトの名無しさん
2008/02/27(水) 14:17:12そういやマクロだからな
言語に組み込むなら、もっと詳細を詰める必要がありそうだな。
0845デフォルトの名無しさん
2008/02/27(水) 20:00:070846デフォルトの名無しさん
2008/02/27(水) 20:04:160847デフォルトの名無しさん
2008/02/27(水) 20:24:16結局、今のところはなし?
0848デフォルトの名無しさん
2008/02/27(水) 20:57:570849デフォルトの名無しさん
2008/02/27(水) 21:06:12n2461か?
0850デフォルトの名無しさん
2008/02/27(水) 21:10:060851デフォルトの名無しさん
2008/02/27(水) 21:18:21間違えた
それ落としてた
0852デフォルトの名無しさん
2008/02/27(水) 21:36:240853デフォルトの名無しさん
2008/02/27(水) 21:38:080854デフォルトの名無しさん
2008/02/27(水) 21:39:000855デフォルトの名無しさん
2008/02/27(水) 21:46:11これは、C++でもC++/CLIでもないのだからVC++の独自拡張としか言えない。
0856デフォルトの名無しさん
2008/02/27(水) 21:56:110857デフォルトの名無しさん
2008/02/27(水) 22:17:540858デフォルトの名無しさん
2008/02/27(水) 22:53:11今のC++への不満を直球で解決しようとしてるだけで、
STLが目指してきたものを蔑ろにしている。
autoとλを組み合わせて制御構造そのものはいじらないのが
正常な進化の方向だと思う。
0859デフォルトの名無しさん
2008/02/27(水) 23:24:30namespace{
void foo(){ std::cout << "anonymous foo" << std::endl; }
}
void foo(){ std::cout << "global foo" << std::endl; }
int main(void)
{
//foo(); //コンパイルエラー
::foo(); //global foo
}
ここで無名名前空間のfooを明示的に呼ぶ方法はあるんでしょうか
0860デフォルトの名無しさん
2008/02/27(水) 23:29:290861859
2008/02/28(木) 00:46:450862デフォルトの名無しさん
2008/02/28(木) 01:23:130863デフォルトの名無しさん
2008/02/28(木) 02:59:44ファイルローカルなクラスや列挙体を囲って ODR 違反を回避する。
0864デフォルトの名無しさん
2008/02/28(木) 12:48:23namespace{
namespace_end.hpp------
}
#include "namespace_start.hpp"
//...
#include "namespace_end.hpp"
0865デフォルトの名無しさん
2008/02/28(木) 19:49:35Koenig lookup対策
0866デフォルトの名無しさん
2008/02/28(木) 19:53:10それってつまりどういうこと?
kwsk!!
0867デフォルトの名無しさん
2008/02/29(金) 01:24:02// A.cpp
struct X { char x; };
// B.cpp
struct X { char y; };
両方コンパイルしてリンクすると同じクラスに対する2つの定義が異なるという
ODR 違反になり、未定義動作となる。
それぞれ無名名前空間で囲っておけば別々のクラスになるので問題なくなる。
0868デフォルトの名無しさん
2008/02/29(金) 02:25:40{
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)は引数にある変数だけがコピーされるんですか?
それともコンストラクタを実行した後のクラスの中身が全部コピーされるんですか?
0869デフォルトの名無しさん
2008/02/29(金) 02:29:210870デフォルトの名無しさん
2008/02/29(金) 09:38:19>>869 ちがうよ。
0871デフォルトの名無しさん
2008/02/29(金) 11:39:50各メンバに対してoperator=を呼ぶんだと思ったが
0872デフォルトの名無しさん
2008/02/29(金) 14:23:35CE環境のプログラム上で、プログラムカウンタを参照する方法ってありませんか?
0873デフォルトの名無しさん
2008/02/29(金) 14:53:55HogeはT型のオブジェクトtを引数で受け取り、そのオブジェクトのメンバ関数Fugaを呼び出します。
ここで、Hogeに渡したtがFugaを持ってない場合、コンパイルエラーになりますが、
コンパイルエラーにせず、Fugaを呼び出さない別の実装に転送する方法はないでしょうか?
0874デフォルトの名無しさん
2008/02/29(金) 15:10:40SFINAE
0875デフォルトの名無しさん
2008/02/29(金) 15:13:44extern int* puroguramu_caunta asm ("pc");
使えるかどうかはしらね
っつうかスレ違い
0876デフォルトの名無しさん
2008/02/29(金) 15:14:01コンパイル時に実装を切り替えるというのは、変態がよく使う。
本当にさまざまな方法がある。
例えば関数のオーバーロードとか、テンプレートクラスの特殊化など
詳しく知りたかったら、C++ Template Metaprogrammingを読め。
で、ある名前のメンバ関数を持っているかどうかってのは、
かなりトリッキーなコードになるので、もっとマシな方法で実装分岐させたほうがいい。
0878デフォルトの名無しさん
2008/02/29(金) 15:25:23ありがとうございます。
試してみます。
スレ違いになるのね…
すみませんでした。
0879デフォルトの名無しさん
2008/02/29(金) 15:36:20http://pc11.2ch.net/test/read.cgi/tech/1203133502/
0880デフォルトの名無しさん
2008/02/29(金) 15:45:33C++ Template Metaprogrammingってよお、買ったけどboost::mplの
リファレンスじゃねーか。Webサイト見たほうがいいわ。
騙された。
0881873
2008/02/29(金) 15:59:28どうもです。
省略符号を使ったテクニックがあったんですね。
C++ Template Metaprogrammingは読んでいませんが、Modern C++ Designは読んだので大体分かります。
省略符号を使って変換可能性と継承を検出するテクニックも書いてありましたね・・。
テンプレートに関数ポインタ渡してメンバ関数の有無検出する方法、思いつかなかったorz
0882デフォルトの名無しさん
2008/02/29(金) 16:07:44>で、ある名前のメンバ関数を持っているかどうかってのは、
>かなりトリッキーなコードになるので、もっとマシな方法で実装分岐させたほうがいい。
トリッキーでもいいけどC++ Template Metaprogrammingって本に何か例が書いてあるの?
0883デフォルトの名無しさん
2008/02/29(金) 16:19:32>>873がどの程度C++を知っているのか分からなかったから、出してみただけ。
ある名前を持つメンバ関数でコンパイル時の分岐がやりたいなんていいだす奴は、
そもそも何も分かってないバカか、本当に自分が言っている事を理解していて、それでもやりたい変態しかいない。
Modern C++ Desingを枕にするぐらいだったら、必要なかったね。
0884デフォルトの名無しさん
2008/02/29(金) 16:29:57void *pvMem = AllocMemory(sizeof(CNode) * num);
CNode *pcNodes = new(pvMem) CNode[num];
for(int i = 0; i < num; i++)
{
pcNodes[i].~CNode();
}
FreeMemory(pcNodes);
これだとダメみたいです。
0885デフォルトの名無しさん
2008/02/29(金) 16:45:480886デフォルトの名無しさん
2008/02/29(金) 16:49:18AllocMemory
FreeMemory
ここで何やってるんだ?
0887デフォルトの名無しさん
2008/02/29(金) 16:49:30×FreeMemory(pcNodes);
○FreeMemory(pvMem);
0888デフォルトの名無しさん
2008/02/29(金) 17:10:19普通、
void FreeMemory(void*);
のシグニチャだと思うけど。
それなら、それでも良いはずなんだが。
0889デフォルトの名無しさん
2008/02/29(金) 17:11:18FreeMemoryでメモリ解放するの特に必要ないかと思って・・・
>>886
AllocMemory(size)
sizeだけメモリを確保
FreeMemory(p)
pが先頭のメモリブロックを解放する
>>887
それもダメでした
0890885
2008/02/29(金) 17:12:51(Effective C++ Item52)
0891デフォルトの名無しさん
2008/02/29(金) 17:15:52>AllocMemory(size)
>sizeだけメモリを確保
特別なメモリ確保のライブラリか何か?
AllocMemoryでnew演算子を使用
FreeMemoryでdelete演算子を使用
なんてことじゃないよね?
0892デフォルトの名無しさん
2008/02/29(金) 17:22:23new するときもひとつずつ placement new するしか無いんでは・・・
0893デフォルトの名無しさん
2008/02/29(金) 17:23:28>特別なメモリ確保のライブラリか何か?
そうです。提供されているもので自作ではありません。ここでは関数名は変えて書きましたが。
>AllocMemoryでnew演算子を使用
>FreeMemoryでdelete演算子を使用
size分メモリ確保してるだけなのでnew,deleteはしていません。
0894デフォルトの名無しさん
2008/02/29(金) 17:24:34AllocMemory(size)でreturn operator new(size);
FreeMemory(p)でoperator delete(p);
と思っていい?
0895デフォルトの名無しさん
2008/02/29(金) 17:24:37そうなんですかね・・・。なんてこった
実はちょっと前にそっちのやり方で作ってたんですけど、確かにそれはきちんと動いていました。
0896デフォルトの名無しさん
2008/02/29(金) 17:25:15それで解釈してもらってけっこうです
0897デフォルトの名無しさん
2008/02/29(金) 17:46:35#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
0898デフォルトの名無しさん
2008/02/29(金) 17:46:56int 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;
}
0899デフォルトの名無しさん
2008/02/29(金) 17:49:46PLACEMENT_NEW=0のtきは落ちない、でした
0900デフォルトの名無しさん
2008/02/29(金) 17:53:23そのせいで使い物にならなかった気がする。
0901デフォルトの名無しさん
2008/02/29(金) 18:00:47ちょっとよくわかりません。もう少し詳しくお願いします
0902デフォルトの名無しさん
2008/02/29(金) 18:07:59ちゃんとなってる?
CNode::operator delete( p, buf );
0903デフォルトの名無しさん
2008/02/29(金) 18:08:21ちょっとまて、placement newしているかどうかにかかわらず、
delete[]が呼び出されるのは何なんだ?
placement newしているポインタに、delete[]したら、鼻から悪魔が出てくるのは当たり前だろ。
あと、placement newしていない場合のコードも鼻から悪魔が出るな。
0904デフォルトの名無しさん
2008/02/29(金) 18:19:49ところで、placement new[]に渡されるsizeはsizeof(T)*Nとは限らないぞ。
そこでメモリ破壊してるんじゃねえの。
0905デフォルトの名無しさん
2008/02/29(金) 18:41:10ttp://www.fides.dti.ne.jp/%7Eoka-t/cpplab-placement-new-3.html
ここのサイトに似たようなことが書いてあったので試しました。
VCではsizeof()*n+4でハングしなくなりましたが、元々の環境ではやっぱりハングしました。
0906デフォルトの名無しさん
2008/02/29(金) 18:43:43ロベールのC++入門講座嫁
0907デフォルトの名無しさん
2008/02/29(金) 18:56:25いろいろ参考になりました。ありがとうございました
0908デフォルトの名無しさん
2008/02/29(金) 20:29:04AllocMemory -> 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バイトが使用されているのかも。
元々の環境では、違うサイズ、あるいは全く異なる実装で配列が管理
されてるのかも。
0909デフォルトの名無しさん
2008/02/29(金) 20:29:59>>906
ではなく
>>907
0910デフォルトの名無しさん
2008/02/29(金) 22:26:37そんなことない。 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
0911デフォルトの名無しさん
2008/02/29(金) 23:18:39>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.
0912デフォルトの名無しさん
2008/02/29(金) 23:45:47class Impl.....抽象クラス
class Default_Impl.....Impl を public 継承 std::vector<Holder> を持つ
これで、Holderのインスタンス作ったらオーバーフローになってしまいました。
調べてみたら、
1, Holder のコンストラクタ
2, Default_Impl のコンストラクタ
3, std::vector<Holder> のアロケータ
4, Holder のコンストラクタ
以下ループ
っということらしいのですが、
どういう設計にすれば上のようなクラスを問題なく作成できるのでしょうか。
0913デフォルトの名無しさん
2008/02/29(金) 23:47:49やりたいことが間違ってるだけにしか見えん。
違うというのなら何がやりたいのか説明してくれ。
0914デフォルトの名無しさん
2008/02/29(金) 23:55:35これ以外に、関数ポインタを受け取れる Func_Impl があって、
Holder(void (*func)(Arg)) : m_pImpl(new Func_Impl(func)){}
のようにHolderを作成できて、
Default_Impl で作ったHolderは上記のような関数を保持するHolderと、
それを複数保持するDefault_Implを保持するHolderを保持したくて、
Holderの operator() で保持してる関数全てを実行するようなクラスを作りたいと思っています。
0915デフォルトの名無しさん
2008/02/29(金) 23:59:05なんで Default_Impl のコンストラクタで引数無しの Holder を生成してるの?
0916デフォルトの名無しさん
2008/03/01(土) 00:06:34>>Default_Impl で作った
は、
Default_Impl を保持するHolder(引数なしHolderのコンストラクタから生成)
でした。紛らわしい表現をしてすみません…。
理想としては
Holder holder;
holder.add(Holder(関数ポインタ1));
holder.add(Holder(関数ポインタ2));
holder.add(holder2); // 別のHolder
holder(); // 全ての関数を実行
という動作をさせたいと思っています。
0917デフォルトの名無しさん
2008/03/01(土) 00:11:15一体何のためにPCなんか参照したいんだ?
0918デフォルトの名無しさん
2008/03/01(土) 00:12:54<new>で定義されてるグローバルの配置operator new(size_t, void*)関数である
new(pvMem) CNode[num]; については、pvMemをreturnしてるだけ。
その後で、コンストラクタが必要な回数だけ実行される。その際、配列の管理が
コンパイラ依存で行われる。
>>904は一般的な配置newについて正しいが、このケースでは<new>のものを使用している
ので>>908、>>910が上手く表現している。
0919デフォルトの名無しさん
2008/03/01(土) 00:37:47とりあえず placement new で領域割り当ててるわけじゃない、という点については >908 の方がより的確なのかもしれないけど。
必要なサイズは sizeof(T)*N じゃない、ぐらいの気持ちで。
もともとの placement new の位置づけからすればこっち(別の割り当て済みメモリ領域にオブジェクトを生成する)の方が主な
使い方の気もするけど、AllocMemory とか FreeMemory に突っ込みが入るようだとあまり一般的じゃないのかなぁ。
で、どっちかというと >887 で指摘されてる点があんまり言及されてないのが気になって。
<new> で規定されてるのは allocation function であって、それ自体は単に渡された値を返していたとしても、
new 演算子の結果 new(pvMem) CNode[num] については、allocation fuction から返ってきた値そのままではないよね?
0920デフォルトの名無しさん
2008/03/01(土) 00:52:14だからさ、 Default_Impl のコンストラクタで引数無しの Holder を生成しなくても
できるだろ。なんでわざわざ生成して当然の無限再帰を引き起こすのさ?
0922デフォルトの名無しさん
2008/03/01(土) 01:16:31std::vector<Holder> を初期化するときにHolderのコンストラクタが呼ばれる、ということでしょうか
呼び出し履歴からHolderの引数なしコンストラクタが呼ばれているのは分かったのですが、
Default_Impl のどこで呼ばれているのかとその対策が分からず困っています。
具体的にDefault_Impl の実装のどこが間違っていて、どう対処すればいいのか、
ヒントだけでも教えていただけると助かります。
0923デフォルトの名無しさん
2008/03/01(土) 01:17:250924デフォルトの名無しさん
2008/03/01(土) 01:18:16Default_Impl の実装を見せずにその間違いを指摘しろとは、エスパーでも募集してんのか?
0925912
2008/03/01(土) 01:29:04実際の物とは違いますが、こちらでも同じ現象が起きてしまいます。
Default_Impl のコンストラクタでは、vector<Holder> の初期化しか行なっていないのですが…
http://sourcepost.sytes.net/sourcepost/sourceview.aspx?source_id=30119
0926デフォルトの名無しさん
2008/03/01(土) 01:32:10> Default_Impl() : m_holder(0) {}
vector(size_type n, value_type const& x = value_type()) が呼ばれてる。
空でいいなら m_holder() でもいいし、何も書かずにデフォルトの初期化に
してしまってもいい。
0928デフォルトの名無しさん
2008/03/01(土) 01:36:56vector<Holder>(0)は、2つの省略可能な引数を持つコンストラクタを読んでる。
そこで、Holder()が生成される。
0929デフォルトの名無しさん
2008/03/01(土) 01:49:02ありがとうございます、無事実行することが出来ました
vector(0) でコンストラクタが呼ばれるはずがない、
という勝手な思いこみで要領を得ない質問ばかりしてしまいましたが、
回答をいただけてとても助かりました。
0930デフォルトの名無しさん
2008/03/01(土) 02:13:47><new> で規定されてるのは allocation function であって、それ自体は単に渡された値を返し>>ていたとしても、 new 演算子の結果 new(pvMem) CNode[num] については、allocation fuction
> から返ってきた値そのままではないよね?
実装依存なので絶対とは言えないけど、ほとんどの実装でそうなっていると思える。
おそらくは配列の要素数を格納するための領域分ずれてる。
実際、配列の要素数は配置new演算子に渡されたアドレスの直後に置かれることが多い。
でも、あくまでも実装依存であって規格では未定義。
でも問題はそれ以前であって、強調したかったのは、規格に従う限りにおいては、
AllocMemoryが戻すアドレスpvMemを配列用の配置構文newに new(pvMem) CNode[num]
のように渡すことさえ問題が起こりうるということ。何故なら、要素数がどこに書
き込まれるかは分からないから。実装を熟知し(配列の管理情報は本当に要素数だけか?
渡すべき正しいアドレスは何か?)、移植性を考えないという条件でのみこれは許され
ることになる。つまるところ、>>908と>>910のドキュメントどおり、ユーザーが確保した
領域に対して配列用の配置構文newを使うことは難しく、常に危険を伴っている。
配置構文newにどのアドレスを渡してよいかは厳密に言うと実装を知らないと判断できない。
0931780
2008/03/01(土) 03:45:16遅くなりましたが解説書きました。
ttp://fiercewinds.net/siki/pub/2008/03/01_032951/
基底クラスで登録洩れがあると破綻するから、嬉しさも中ぐらいだなぁ。
あと、ファクトリー関数の場合は共変の戻り値を使う=関数に指定クラスが含まれることが多いので、
ここまで面倒臭いことしなくても簡単にコンパイルエラーに持って行けそうな感じがします。……試さないけど。
0932デフォルトの名無しさん
2008/03/01(土) 05:15:20メリットないだろ。
配列用の配置構文が使い物にならんのは
つまりそういうこと。
0933デフォルトの名無しさん
2008/03/01(土) 09:45:520934デフォルトの名無しさん
2008/03/01(土) 11:52:04つまらないこと言うなよ。
やるなと言えばそれまでだが、やったらどうなるの?
に対する回答にはならん。
0935デフォルトの名無しさん
2008/03/01(土) 14:47:10あとから確認するときに、場所を特定するために残しておきたいんです。
0936デフォルトの名無しさん
2008/03/01(土) 15:54:47明らかに回答ではないんだから(現在の話題に関して「思ったこと」を書いてるだけ)、
別に回答になっていなくても問題は無いと思うよ。
質問から始まった話題について何か書き込む時は、絶対に回答としての機能を
持っていなければならない、という信念があるとしたら、もうちょっと柔軟になったほうが・・・。
0937デフォルトの名無しさん
2008/03/01(土) 17:09:41もしそのコードを実行してしまったら何が起こるか予測できないって事
placement new
は将来のために予約されたものだと俺は思ってるから
積極的に使うものじゃないと思う。
コレ使ってるライブラリって見たことない。
0938デフォルトの名無しさん
2008/03/01(土) 17:46:29std::allocatorのconstruct
0939デフォルトの名無しさん
2008/03/01(土) 18:35:31そうなれば多少マシになるんじゃないの
0940デフォルトの名無しさん
2008/03/01(土) 18:56:23サンクス
ユーザレベルなら
std::allocator
boost::pool_allocator
あたり使ったほうがいいですよね?
0941デフォルトの名無しさん
2008/03/01(土) 19:00:45placement new 使いたいためにわざわざ std::allocator の construct 使うの?
なんで? placement new 使えばいいじゃない。
0942デフォルトの名無しさん
2008/03/01(土) 19:06:33たとえば今のPCは、今居る関数のポインタ値にだいたい近いよね。
それじゃダメなの?
0943デフォルトの名無しさん
2008/03/01(土) 19:08:080944デフォルトの名無しさん
2008/03/01(土) 19:12:130945デフォルトの名無しさん
2008/03/01(土) 19:21:55ドットイートのようなゲームを作りたいんですが、
どうしてもドットを食わず、素通りしてしまいます。
自機がドットを通ると道になるようなプログラムは
どうしたらできるんでしょう?
0946デフォルトの名無しさん
2008/03/01(土) 19:33:220947デフォルトの名無しさん
2008/03/01(土) 19:37:080948デフォルトの名無しさん
2008/03/01(土) 21:35:06今はどうやってるんだ
まずそれを説明してみろ
0949デフォルトの名無しさん
2008/03/01(土) 22:20:472種類の書き方が存在するみたいだけど、どっちも一緒ですか?
あと、使うならどっちが望ましいんでしょう。
0950デフォルトの名無しさん
2008/03/01(土) 22:28:22template template parameter つまり template<template <typename T> class U> の時だけは class じゃないと駄目。
趣味の問題だから好きな方を使えば良い。
0951デフォルトの名無しさん
2008/03/01(土) 23:42:52class A
{
private:
typename T::B m_abc;
}
のときはtypenameじゃないとだめ
0952デフォルトの名無しさん
2008/03/02(日) 02:45:45unsigned long int r=600000000000
だとinteger constant is too large for "long" type
といエラーが出てしまいました。
0953デフォルトの名無しさん
2008/03/02(日) 02:49:33厳密な精度が要らなければ double などの不動小数点数を使うといい。
そうじゃなければ多倍長整数を使うことになるでしょう。
0954デフォルトの名無しさん
2008/03/02(日) 02:50:56long long int int r=600000000000;
0955デフォルトの名無しさん
2008/03/02(日) 02:51:28long long int r=600000000000;
0956デフォルトの名無しさん
2008/03/02(日) 11:09:17とはいえ、今の所規格上はそういう型はないしなあ。
まあ、規格で int が 32 ビットと決まってるわけではないから
int が 64 ビットの場合もあるわけだが。
まあ、環境によって
typedef unsigned __int64 UINT64;
か
typedef unsigned long long UINT64;
かを定義すればいいよ。
0957デフォルトの名無しさん
2008/03/02(日) 11:54:06目的によって double, 多倍長整数, UINT64, BCD など変わってくるだろ
0958デフォルトの名無しさん
2008/03/02(日) 12:26:33つuint64_t
0959デフォルトの名無しさん
2008/03/02(日) 12:33:250960デフォルトの名無しさん
2008/03/02(日) 12:34:590961デフォルトの名無しさん
2008/03/02(日) 13:46:110963デフォルトの名無しさん
2008/03/04(火) 15:41:12コンパイラのデータモデルを調べよう
>>958のようにデータモデル別に定義してくれてるライブラリの型を使うのが安泰
代表的なのだと、gcc4がILP32,LP64、vc++がILP32,LLP64など、
組み込み系だとLP32なんて曲者もあるから困る
0964デフォルトの名無しさん
2008/03/05(水) 17:18:50そのとき、hogeのメンバ関数も使いたいのですが、STLを使った場合だと
x.piyo()みたいではアクセスできません。 どうすれば解決できるんでしょうか?
0965デフォルトの名無しさん
2008/03/05(水) 17:26:580966デフォルトの名無しさん
2008/03/05(水) 17:28:45xの中には複数のhogeがあるだろ?hogeのリストなんだから
どのhogeのpiyoを呼びたいんだよ?って話
全部のhogeについて呼びたいんなら、
for (list<hoge>::iterator i = x.begin(); i != x.end(); i++)
i->piyo();
0967デフォルトの名無しさん
2008/03/05(水) 19:44:330968デフォルトの名無しさん
2008/03/05(水) 23:23:040969デフォルトの名無しさん
2008/03/06(木) 03:22:340970デフォルトの名無しさん
2008/03/07(金) 08:21:130971デフォルトの名無しさん
2008/03/07(金) 14:06:570972デフォルトの名無しさん
2008/03/07(金) 14:51:050973デフォルトの名無しさん
2008/03/08(土) 18:20:350974デフォルトの名無しさん
2008/03/08(土) 20:52:300975デフォルトの名無しさん
2008/03/09(日) 10:28:27console?character?
0976デフォルトの名無しさん
2008/03/09(日) 11:51:19c++
0977デフォルトの名無しさん
2008/03/09(日) 13:29:11でもincludeできなくなるのは困るな。
assertも無くなると困るな。
0978デフォルトの名無しさん
2008/03/09(日) 13:29:420979デフォルトの名無しさん
2008/03/09(日) 16:02:380980デフォルトの名無しさん
2008/03/09(日) 16:15:09何が違うんでしょうか?
0981デフォルトの名無しさん
2008/03/09(日) 16:24:220982デフォルトの名無しさん
2008/03/09(日) 16:27:351.クラススコープでしかできない演算子がある。
2.クラススコープの場合、第一引数(this)に暗黙の変換が適用されない。
二項演算子などで引数の対称性を表現できない。
3.非クラススコープで、非public部へアクセスする場合カプセル化の度合い
を弱めることになる。
0983デフォルトの名無しさん
2008/03/09(日) 16:28:49console
0984デフォルトの名無しさん
2008/03/09(日) 18:07:310985デフォルトの名無しさん
2008/03/09(日) 18:11:310986デフォルトの名無しさん
2008/03/09(日) 18:12:580987デフォルトの名無しさん
2008/03/09(日) 18:19:050988デフォルトの名無しさん
2008/03/09(日) 18:19:520989デフォルトの名無しさん
2008/03/09(日) 18:21:170990デフォルトの名無しさん
2008/03/09(日) 18:33:53だから巡るんだよ
本でもサイトでも1つだけを参考にするのは良くない
0991デフォルトの名無しさん
2008/03/09(日) 18:34:031の理由が2という理解であってますか?
またstaticなメンバやグローバル関数にできない演算子は
= () -> [] の四つであってますか?
入門書はC++Primerの英語のを読んでるけど、分厚くて萎えまくりです。
0992デフォルトの名無しさん
2008/03/09(日) 19:00:380993デフォルトの名無しさん
2008/03/09(日) 19:21:03質問者は入門、つまりC++を理解し始めたいのであって、
言語仕様書の日本語訳を探してるわけじゃないんだよ
0994デフォルトの名無しさん
2008/03/09(日) 19:26:51くだらないこと言ってないでサイトでも本でもお薦めを教えてやればいいのに。
0995デフォルトの名無しさん
2008/03/09(日) 19:29:25後々、あれは失敗だったなと思うこともあるけどそれも経験だ。
原書含め数十冊読んだが、常に手元に置くものは自然と
決まってくる。それが自分のベストセラー。
0996デフォルトの名無しさん
2008/03/09(日) 19:31:260997デフォルトの名無しさん
2008/03/09(日) 19:34:13http://pc11.2ch.net/test/read.cgi/tech/1204124499/l607
0998933
2008/03/09(日) 19:35:44だから俺は複数のサイトを自分で巡って見たほうが良いと言っているんだが・・・
むしろお薦めの本を教えてやればいいのは、巡っても意味無いと言う>>992とかだろ?
0999デフォルトの名無しさん
2008/03/09(日) 19:42:43質問するならこっちの方が良いよ、ここと違って親切な人多いし
http://pc11.2ch.net/test/read.cgi/tech/1202273631/
1000デフォルトの名無しさん
2008/03/09(日) 19:43:56質問者の趣旨を汲むならね
10011001
Over 1000Threadもう書けないので、新しいスレッドを立ててくださいです。。。
レス数が1000を超えています。これ以上書き込みはできません。