STLつかうと一気に実行ファイルサイズが10倍に?! 環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。 C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの? #include <stdafx.h> 後死ね。 言葉が悪いな。それで教えているつもりか。 まぁヒントぐらいにはなったな。 うむごくろう。
天ぷら終わり(・∀・)
乙
C言語から移ってきた者です。
C++でのプログラミングって、さっさと書いて作るのを優先して
コードの最適化とかの作業は後回しにすべきなのでしょうか?
それとも最初に書くときから細かい所の最適化に気を配るべきなのでしょうか。
前スレの
>>890 template<typename T>
void foo(const T& arg){
if(T::hoge_flag){
func_true(arg);
}
else{
func_false(arg);
}
return;
}
とかです。
>>11 そんな事一概に言えないだろ
組み込みに使うのかPCで使うのか、開発期間や費用によっても違うし
ただ大規模なプログラムなら、最適化よりもバグの出にくいコーディングを
真っ先に心がけるべき
致命的なバグのあるソフトは価値がない
>>12 ありがとうございます。
やっぱり一概には言えませんよね。
> 致命的なバグのあるソフトは価値がない
肝に銘じておきます。
>>12 組み込みのことは知らないが、
開発期間が少ない→最適化は後
費用が少ない→最適化は後
大規模→最適化は後
じゃない?
>>13 ギャンブル・・・つまりコンパイラが
本当に最適化してくれるかは分からないという
ことですね。
むしろ 最適化が先ってあまり聞かないよな。 ・・・必死に最適化しといて、やっぱりそこ使わなくなった なんてことがたまにあったりして泣きそうになる。
>>16 うん。その細かいところがボトルネックになるかどうかなんてトータルで動かさないとわかんない
設計さえちゃんとしてれば後からボトルネック部分を解消するのはうまくいく。
いつでも瞬時に最適なコードを書けるスーパーハカーなら全力で書けばいいと思うけど 並のプログラマならパフォーマンスが足りないと思ったときにプロファイラ見ながら アルゴリズムを変更したり最適化を詰めていったりするのが現実的なところじゃねの
20 :
11 :2010/03/18(木) 11:03:43
>>19 みなさんありがとうございます。
細かいことがいちいち気になって先に進めない性格なのですが、
とりあえず書き上げて完成させてから最適化を考えようと思います。
80/20の法則、あるいは70/30の法則ってのがある プログラム全体の実行時間の70%〜80%を20%〜30%の部分が占めている という有名な法則だ 要するに全部書き上げてからプロファイラなどで速度のボトルネックになっている 部分を20%〜30%程度書き換えるだけで十分速くなるという事だな
>>21 Effective C++で紹介されていた経験則か。
パレートの法則
時期早尚な最適化はうんちゃら
動かないものは最適化以前の問題だからなぁ
80:20でなくても常識的に考えてクリティカルな部分だけ最適化すればいいだけの話だろ。 実行速度に支障がでなければおk 「全部最適化しないと遅くて使えない!」っていうんならプロジェクト全体がクリティカルなだけ。
>>27 そんなプログラムは死んでも組みたくないなw
>>27 > 「全部最適化しないと遅くて使えない!」
そりゃプロジェクト自体が無謀なんだろうなwwww
30 :
デフォルトの名無しさん :2010/03/18(木) 16:45:01
0と-0って、何か違うのでしょうか。 出力させるときに2通りあるような気がします。 よろしくお願い申し上げます。
+0.0001 の小数を切り捨てると 0 -0.0001 の小数を切り捨てると -0
実行速度の最適化は後でやればいいけど 読みやすさの最適化はちょくちょくやった方がいいと思うの
それは最適化というか書き方の習慣
>>31 なるほど。
出力させると違うけど、値としては同じなのですか?
-0==0
は規格でどうなっているのでしょうか?
最適化が不要な状態が最適
>>34 値が同じだったらなんで出力が変わったりするんだい?
普通は「aもbも出力すると同じなのにa==bが真になりません、なんでですか?」
という質問をする。
>>34 規格では符号bitが異なるだけだとおもうよ。
38 :
34 :2010/03/18(木) 18:26:20
「値が同じ」を「データのビットパターンが一致」だとすれば-0と0で出力が分かれる値は「別の値」だが、 「演算子'=='がtrueを返す」だとすればそれはC++規格上浮動小数点数の処理系依存
ヒープ領域にデータを確保する関数、それを開放する関数(hogeとします)をメンバ関数に持つクラスがあります。 このクラスのデストラクタ関数内で、hogeを呼び出すのってありですか? デザイン的にあまりよろしくないとかありますか?
別によろしくない訳ではない。 それが仮想関数だと公開スコープとかによっては考え物。
42 :
34 :2010/03/18(木) 19:11:58
>>39 ああ、なるほど。
> 「演算子'=='がtrueを返す」だとすればそれはC++規格上浮動小数点数の処理系依存
処理系依存なのですか。
ありがとうございます。
三項演算子ってバグの温床じゃねぇ? テンプレートと組み合わせて使ったら死にそうな思いをしたよ。 Conceptさんが居れば全部丸く収まるのかなぁ。
死に損なったていうなwww 悪夢はVC++にて発生した。 気付いちゃえば簡単だったんだが、 boolean ? ClassA() : flag ? ClassB() : ClassC() で、ClassBがClassA型に暗黙に型変換できなかったみたいで、 じゃあ逆にキャストしてくれよと思ったがそれがなんかうまくいかなかった。 (ClassCの兼ね合いか?) うん、うまく説明出来なくてゴメン。 ネストされたtemplateが変に絡み合っていて、 VC++の吐くエラーメッセージがここから発生してないところがミソだった。 テンプレートコンストラクタのところがおかしいみたいなこといわれて その辺を頑張ってデバッグしてしまっていた。 結局 boolean ? static_cast<ClassB>(ClassA()) : flag ? ClassB() : ClassC() これで全部解決したのだが、泣きそうになった。
>>40 パターン的には呼び出さない方がおかしいと思うよ。
>>43 俺は特に三項演算子で問題になったことはないなあ。
三項演算子 C?A:B は型を持つから、AとBの型を意識してないと
テンプレートの特殊化が思い通りにならない、ということはあるかもしれん。
autoさんが居ればif文に書き換えやすくなるから多少楽になると思う。
可読性に由来するバグか
式からパースと要素からパースの一例すね
>>45 flag ? ClassB() : ClassC()の部分の型ががClassCになって、
ClassCとClassAの間で変換できないからエラーになったと見た
foreachでまさか三項演算子の型のシステムが役立つだなんて だれが想定したろうかww
52 :
45 :2010/03/18(木) 21:28:04
というか三項演算子が悪いんじゃなくて、 そこが悪いと言わずに テンプレートコンストラクタのところがおかしいみたいなことを 言ってきたコンパイラが悪いんじゃねぇかという気がしてきた。 あと、VC++ではこの様に通らなかったのに gccではコンパイルが通って正常動作していたところが さらに俺の涙を誘った。
生きてて良かった 俺も気をつけよう…っつか、うち三項演算子禁止だw
デザパタ関連の本を読んでもデザパタが使えない。 うまく頭に落ちてこない…
無理に使う必要ないでしょ
>>54 デザパタは知ってるだけじゃ何に使えるのかわからない。
しかし、使うべきときがくれば勝手に覚える。
実際に書いてるコードがデザパタに合致することがよくある。そのときデザパタの知識があれば、有効に使える。
デザパタという形でコードに名前がついてるのは非常に便利。
テンプレートメソッドなんかはあらゆる場面で出番があるよ STLのアルゴリズム、 for_each とかはその典型だ コンテナのアロケータなんかはストラテジーパターンだ mem_fun や bind1st とかはアダプターパターンだ
デザパタに合致することは確かによくある →じゃあデザパタの名前は別に覚えなくていいか →設計時の会話で使うので結局名前も覚えないといけない
型の調整は面倒だよな。ホント。 static_cast<void>とか最近まで知らなくて、わざわざvoid用に特殊化してたよ。
なぜ
>>45 で三項演算子が悪いって結論にいきつくのか、オレにはよくわからないな
職場でデザパタで会話したこととかないな
パターンつっても、よりイディオムとして細分化されてたり
あるいは複合してたりもするせいか、
あまりデザパタの名前に実益を感じたこともない
>>52 だからやっぱり三項演算子が悪いわけなじゃいなと
彼も結論づけているようだぞ。
そもそも職場にデザパタという言葉を知ってる奴がいない
63 :
61 :2010/03/19(金) 00:08:00
>>60 コードレビューしたときに、ここオブザーバパターン使えるんじゃね?とか。
boostが使えない環境でboost::optional<>的な物を使用したいので自作をと考えています 一番簡単なのはT* tを内部に持ってTを動的生成して 未初期化のときはNULLポインタを持つ事で区別、だとおもうのですが 使い方によってはnewによる動的生成を繰り返す事になりそうですが、やはりコスト高になってしまうでしょうか?
>>65 そりゃnewしないのと比べればコスト高だろうが、それが対象のアプリで問題になるとは
限らない。実測しないとわからないよ。
>>65 簡単な実装方法として、デフォルトコンストラクタのコストを無視できるとするならば、
template class<T>
class opt
{
>>65 簡単な実装方法として、デフォルトコンストラクタのコストを無視できるとするならば、
template class<T>
class opt
{
bool valid;
T value;
};
もし、気になるなら placement new を使う。
class opt
{
bool valid;
char value[sizeof(T)]; //ここにplacement newを行う。
};
素朴な質問を 1、普通のテンプレート関数は実態が一つにまとめられるようですが 特殊化で型が確定したテンプレート関数は一つにまとめられない? (VCでそんな感じのエラーが) 2、仮想関数を持つクラスのサイズが、無いクラスより大きくなるのは コンパイラ依存?仮想化テーブルを持たせない実装も存在する? 気が向いたらでいいので教えてください。
質問 stringクラスのインスタンスがあったとき、 そのインスタンスが構築された際のコンストラクタにNULLが 引数として渡されたかどうかを確かめることは出来ますか? string s(NULL);
>>70 それ規格に違反してる
NULLで初期化は許されていない
>>69 基本はプログラム中に同じものの定義はひとつだけ(ODR)なんだけど、
いくつか条件付で複数の定義が認められているものがある。
規格の 3.2 p5 より。
> There can be more than one definition of a class type, enumeration type,
> inline function with external linkage, class template, non-static
> function template, static data member of a class template, member
> function of a class template, or template specialization for which some
> template parameters are not specified in a program provided that each
> definition appears in a different translation unit, and provided the
> definitions satisfy the following requirements. ...
順に並べ上げると、
・クラス
・列挙
・外部リンケージを持つ inline 関数
・クラステンプレート
・非 static 関数テンプレート
・クラステンプレートの static データメンバ
・クラステンプレートのメンバ関数
・いくつかのテンプレート引数が特定されていないテンプレート特殊化
が該当する。こいつらは複数のコンパイル単位にあっても、それらが同じ内容で
あれば(この条件の詳細は上記の引用の続きにある)認められる。
「特殊化で型が確定したテンプレート関数」はこれらに該当しないので、定義を
ひとつだけにする(.cppに置く)必要がある。
>>71 ありがとうございます
でも警告も出ずにコンパイルは出来ちゃうんですよね。g++
実行時に吹き飛ぶんだからそこで気がつけというのが常識として認知されているということですね
>>69 仮想関数を持つためにはどうしてもオブジェクトに情報を足さないといけないので、
サイズを増やさないような実装は思いつくだけでも困難だと思う。おそらく存在しない。
>>72 、74
わかりました。ありがとうございました。
printfで表示する代わりにstd::stringを返す関数が書きたいのですが ヒントだけでも教えてもらえないでしょうか vsprintfのstd::string版があればいいのですが
>>78 vsprintf()の結果を返せばいいだけではなくて?
>>78 boost.format
boostが使えないのなら、vsnprintf()を使って自作するんだね
少なくともgccとVC++では使えるが、戻り値の仕様に差異があるので注意
sprintfしてstringにする
>>73 NULLはC++の標準のマクロじゃないよ。
C++というかSTLではNULLを使わなくてすむようになっている。NULLを使わなければ、実行時に吹っ飛ぶ可能性は減らせる。
いかにもツッコミが入りそうな書き込みだな
stringにNULLなんか突っ込んで何する気だったんだ
突っ込む以前に
>>83 が何を意図してるのか理解できなかった。
>>70 コンストラクタを呼ぶ前にNULLでないかチェックすればいい。
コンパイラはコードが文法的に正しいかをチェックしているのであって、
プログラマーの意図に沿っているかをチェックしているわけではないよ。
>>78 std::stringにはconst char*を受け取るコンストラクタがある。
char[BUFFER_SIZE] buff;
sprintf(buff, "うんたらかんたら");
return std::string(buff);
出力形式にあまりこだわらないならstd::stringstreamを使った方が無難。
ttp://codepad.org/OIrlaNZc (ごちゃごちゃしていてすみません。)
このコードで、
NS_C::get_tripled(const T& arg)
で、
if(T型を受け取る自前のget_tripledが用意されている){
〜〜
}
としていますがこんな分岐をコンパイル時に出来ませんでしょうか。
テンプレートメタプログラミングを使っても、無理でしょうか。
つまり、自前のget_tripled関数が用意されているClassAのときは
NS_C::get_tripled<ClassA>はそちらを呼び出して返すだけのコードが生成され、
自前のget_tripled関数が用意されていないClassBのときは
NS_C::get_tripled<ClassB>は代替実装を用いて返す
ということです。
よろしくお願い申し上げます。
>>88 ありがとうございます。
それでいけました。
90 :
87 :2010/03/20(土) 12:45:42
どうして
>>88 のコードでちゃんと希望どおりに動くのでしょうか。
std::swapの特殊化では、
using std::swap; swap(〜, 〜);
としておけば特殊化したswap<MyClass>があればそちらが選ばれ,
もしなければstd::swapが選ばれるというルールがあるため
うまく解決するということはEffective C++に書いてあった
のですが、今回のケースでは特殊化とは違いますよね。
私の考えでは
//////////////////////////////////////////////////////
NS_A::ClassA中でfriend宣言されているget_tripled関数は、
NS_A::ClassA<double> a=20;でNS_A::ClassA<double>がインスタンス化されるのと
同時に 生成され、その関数はテンプレートではない。
すなわち
@非テンプレート関数double NS_A::get_tripled(const ClassA<double>& arg){return arg.num*3;}
が生成される。
A一方NS_C::get_tripledは関数テンプレートであり、こちらもオーバーロード解決の候補になる。
だが、非テンプレート関数@とテンプレート関数Aでは前者が優先されるという
ルールがあるため、@が選択される
//////////////////////////////////////////////////////
と思うのですが、これで合っていますでしょうか?
>>90 >同時に 生成され、その関数はテンプレートではない。
どちらもテンプレートパラメータがあるんだからテンプレートでしょ
friend関数側の方が優先されるのは、引数の推論が働いた時に
friend関数のconst ClassA<T>&という引数の型がClassA<double>に対して
NS_Cの関数の引数であるconst T&よりも一致するから
92 :
87 :2010/03/20(土) 14:05:44
>>92 今調べてみたがオレの間違いだ。申し訳ない
>>90 で正しい
Barton-Nackmanトリックってやつで
クラステンプレートのインスタンス化に伴って、
テンプレートではない関数を生成できるようにする手法らしいね
テンプレート引数の推論を必要としないから通常の多重定義のルールに従うそうだ
94 :
87 :2010/03/20(土) 15:55:12
>>93 超ややこしいですね。
お手数おかけ申し上げてすみませんでした。
ありがとうございました。
それ、Barton-Nackman trickなんて名前が付いてたんですね。
便乗質問させてください。
クラステンプレートは、それをインスタンス化させても使われていないメンバ関数までは
インスタンス化されず、バイナリにも含まれないと習った気がします。
これは
>>87 氏の NS_A::ClassA<T>をT=doubleでインスタンス化させても、
使っていないメンバ関数(ないですけど、仮にあったとしたら)はインスタンス化されないということ
だと理解しています。
ではBarton-Nackman trickで
@非テンプレート関数double NS_A::get_tripled(const ClassA<double>& arg){return arg.num*3;}
が「生成」されるとありますが、この場合は
例え使われていなくても必ずバイナリにも含まれるのでしょうか。
以上の話はexplicit instantiationしていないものとして、です。
(explicit instantiationしていたら含まれるでしょうが。)
どなたかよろしくお願い申し上げます。
97 :
95 :2010/03/20(土) 17:49:52
>>96 ありがとうございます。
そうやって調べる発想には到底至りませんでした。
Comeau C/C++のWebサイトで試しても通りましたので、
含まれないようですね。
感謝申し上げます。
某ページでこんなん見つけた。
class string {
public:
string(const char*);
} ;
void f(string, string, bool = false) ; // 1
void f(string, bool = false) ; // 2
void g()
{
f(“Hello”, “Goodbye”) ;// 2が呼ばれる
}
なぜか。まずオーバーロードの解決をするために、一つ目の引数を見る。
これはどちらの関数も、string型を取る。string型はコンストラクタにconst char *型を取るので、
コンパイラはstring型に変換できる。二つ目の引数はどうか。関数1はstring型を引数に取るが、
関数2はboolである。人間的に考えると、関数1を呼んで欲しい。し
かし、規格では、関数2が呼ばれるのが正しい挙動だ。
なぜかというと、コンストラクタを使って変換するより、ポインタをboolに変換するほうが、
規格上、より高い候補になるからだ。そんなわけで、コンパイラは、関数2を、正しく、呼ぶことになる。。
ttp://cpplover.blogspot.com/2008/06/coverload-resolution.html 言われてみればなるほどと思うけど、なんて気持ち悪いんだ。
つまりコンストラクタにはちゃんとexplicitをつけろと
>>99 この場合だとどのコンストラクタにつければいいん?
なんかclass設計の基準がわからないんだが 全てのコンストラクタに付ける? それとも暗示的に変換して欲しいの以外につける? それとも全部つけないで呼び出し時にキャストする? 普通はどんな感じにしてるんだ?
>>102 クラス設計として暗黙変換を必要としているとき以外は、暗黙変換を許さないように付ける。
安全重視。
そうなのか・・・ 今まで良くわからなかったからまるで付けてなかったけど ちゃんと付けることにするよ
constと比べればexplicitなんて可愛いもんだ。
>>105 explicitを付け忘れてもコンパイラは涼しい顔でコンパイルしてしまうけど、constはエラーが出るから楽だよ。
107 :
100 :2010/03/20(土) 22:46:08
>>101 string::string(const char*);
か。
operator bool()を出すクラスにconstructor explicitだな
つまり文字列リテラルを受け取るboolクラスにexplicitを つければいいわけですね わかります
111 :
デフォルトの名無しさん :2010/03/21(日) 01:12:22
template <class Iterator, class Distance> void advance(Iterator& iter, Distance offset) { std::_advance( iter, offset, typename iterator_traits<Iterator>::iterator_category() ); } の実引数typename iterator_traits<Iterator>::iterator_category() の意味[特に最後の()]が さっぱりわかりません。これ、無名オブジェクトのコンストラクタなんですか?
>>111 「typename iterator_traits<Iterator>::iterator_category」型のコンストラクタを呼び出している。
この型はイテレータの種類(単方向/双方向/ランダムアクセス)を特定するために使われている。
(詳細は
http://www.sgi.com/tech/stl/iterator_traits.html など)
多分std::_advanceはテンプレート関数で、イテレータの種類ごとに特殊化されて、
最適な方法でイテレータの増減を行うようになっている。
テンプレート関数なので引数からテンプレート引数を推定させることができて、
型情報を伝えるために、無名オブジェクトを渡している。
113 :
デフォルトの名無しさん :2010/03/21(日) 09:01:08
ありがとうございます。
Testクラスを継承する全ての派生クラス(たくさん!)に一気にfriend指定したいのですが良い手はないですか? friend class Test; はダメでした。
>>114 ないです。
わざとそう言う仕様になっているのです。
じゃないと他人がTestクラスを継承して作ったクラスでそのクラスにアクセスできちゃうじゃない。
単体テストでもしたいのかな privateメンバ関数のテストとか
Testにそのfriendにしたクラスのアクセサ作るとか
118 :
114 :2010/03/21(日) 12:13:08
ユニットテストのためです。 無理を承知で何とかなりませんか?
#define class struct
>>118 テストの時だけpublicにしちゃえば?
#ifdef DEGUG
#define private public
#define protected public
#endif
って。
>>119 だからそれじゃコンパイルが通らないこともあるんだって
前スレから俺が言ってるじゃないか!!
template <class T>
に適用してみ。
>>121 template <typename T>
と書いとけばいい話
123 :
114 :2010/03/21(日) 12:46:11
>>120 良いアイディアだと思うのですが、それもちょっと。
もしくは可能なら
friend namespace UnitTest;
でも良いです。
とにかくユニットテストからprivate変数にアクセスしたいのです。
3項演算子がocamlのifに似てると思ってやってきたら
>>43 以降で話題になっていたでござる
125 :
120 :2010/03/21(日) 12:48:06
>>123 全てをfriend指定しないで
>>120 しないのに
全てからprivate変数にアクセスしたいわけでしょ。
さすがにマジで不可能。
126 :
114 :2010/03/21(日) 12:55:22
不可能なのは分かるのですが、そこを何とかしてしまうスーパーハッカーは居ないですか
128 :
114 :2010/03/21(日) 13:04:03
ださい。デバッグ版とリリース版で(厳密に言えば)ソースが違うのが問題かと
擬似リフレクションするとか インスタンスアドレスからのオフセットを頑張って取得 多重継承でも絡んでないかぎりイケるんじゃね
というか単体テストだろ public/protectedメンバ関数を叩いたときの挙動さえ確認しとけばいいんじゃないのか privateをわざわざほじくり出してその関数だけでテストして何になるんだ?
関数の途中だけぶった切ってテストするのと似たようなもんだな
>>118 Testからfriend指定したクラスや関数は、派生クラスの新規メンバーを知らないんだから
できても意味がなくね?
簡単なソースだしてみ?
クリアボックステストは最初の挙動を確認する段階だけだろ。 基本はブラックボックじゃね?
ホワイトボックスのことをクリアボックスとも言うのか?
>>128 例えば
#define explicit
だったらこれでオーバーロード解決が変わったりするから
デバッグ版とリリース版で(厳密に言えば)ソースが違うといえるけど、
private指定をpublic指定にする場合では、
コンパイルエラーにはなるかもしれんが
オーバーロードの解釈が変わったりはしないじゃん。
そうでなきゃもう設計が合わないとしか言わざるを得ない。
>135 超マイナー。ホンの一部しか使用していないね。 ホワイトボックスよりも判りやすいけど。
『Exceptional C++』を読み始めました。 『Effective C++』を読んだときのように目から鱗が落ちる思いですが、 それにしても難しすぎませんか? 『Effective C++』は間を空けて2周読み大体理解したつもりなのですが、 『Exceptional C++』もやはり全部 理解しないとダメでしょうか。
Effective C++でさえ鬼の難しさなのに、それ以上難しいとな?
例外を本格的に使うつもりなら全部理解しないとダメ 使わないなら理解しなくてもいいけど知ってた方がいいことには変わりない
141 :
138 :2010/03/21(日) 23:27:48
>>140 ありがとうございます。
私は積極的に使いたいわけではないのですが、このご時世、
いつまでも逃げ切れない気がするんです。
うひー
本格的に使うも何も、ライブラリやフレームワークやら リンクした他人のモジュールが例外を投げてくるかもしれんから 例外安全は常に考慮すべきと思うがね depthシリーズって似た名前が多いから どの本に何が書いてあってあったか記憶が薄れてきてるけど たしかMoreも読まないと補足されてない事があったような
143 :
デフォルトの名無しさん :2010/03/22(月) 01:59:32
C++は平均的なプログラマーが単純に書くと10行程度になる記述を3行で書くためにヘッダーファイルに50行書いてしまう言語。 また、そのためのルールのために10ページ追加する言語。 糞過ぎですよね?
まあ、糞だと思う人もいるね 糞だと思うならC++以外の言語を使えばいいだけのこと C++の言語仕様を決めてる人達の考えは 嫌なら使わなければいい ってことなんじゃないかな?
速度の為ならどんな面倒なことも行いますっ
すみません こんな風に文字列テーブルを初期化したいんですが どう書けばいいんでしょうか class MyClass { private: WCHAR * table[] = { "aa", "bbb", "あ", "c" }; }
>>146 はL付きでした
VC++でコンパイルしてみると
error C2059: 構文エラー : '{'
というエラーが出ます
class MyClass
{
private:
WCHAR * table[] = { L"aa", L"bbb", L"あ", L"c" };
}
>>118 Testを継承させたということは単体テストをする前提でコード書いたんだろう。
はじめからテストすることを前提に書いたものに「friend指定が必要だった!」とか言っても
単なるオマヌケでしかないなあ。
>>146 無理。現行のC++の規格ではメンバ変数の宣言でその初期化を指定することはできない。
更に、メンバ変数の配列の初期化は面倒くさい。
class MyClass
{
private:
WCHAR * table[4];
public:
MyClass()
{
this->table[0] = L"aa"; this->table[1] = L"bbb";
this->table[2] = L"あ"; this->table[3] = L"c";
}// end of ctor
};// end of class
C++0xが来たら
>>147 みたいな書き方ができるかもしれない?
>>149 ありがとうございます
一つずつ入れていきます
}// end of ctor };// end of class 丁寧なコメントだが、漏れにはウザく感じる
実装が一画面に収まらなくなったら書く様にしてるけどな ::名前空間::定義名も含めて
いや、いいんだよ書いても 親切だしね ただ漏れ個人が、余計なものに感じてしまうだけ
154 :
デフォルトの名無しさん :2010/03/22(月) 04:38:15
L"aa"のLってどういう意味ですか?
ワイド文字列リテラルの書き方だというのは知った上で、 何故Lでそれを表現するのか、というのを訊いてるのかな? そういや何故なんだろう。
LongのLだと思ってたが違うのかね
L"ab" == static_cast<short>{'a','\0','b','\0'}
Long の L でしょ
数値で L を最後に付けるのに合わせたんだと思う
>>157 突っ込みどころ満載で突っ込む気も失せるくらいひどいな
L"ab" を L"" を使わないで笑わせよ。
>>147 table が変更されない単なる文字列テーブルなら静的メンバを使用する事は可能だ
class MyClass
{
private:
static const WCHAR* table[];
};
const WCHAR* MyClass::table[] = { L"aa", L"bbb", L"あ", L"c" };
MyClass のインスタンスに table の実態は存在せず外部変数として定義した領域へのリンクみたいなイメージとなるので
美しくないと言われればそれまでだが記述は簡単だ
>>146 関数内にstatic constなテーブルを持ちそのポインタを返す初期化関数を用意して、コンストラクタで呼ぶ。
>146で言うtableを動的に使いたいなら、上に書いたポインタからコピーする関数も用意する。
sizeof table がきちんと動作することを期待してんじゃないの? 残念ながら無理だけど // .h側 class MyClass { private: static const WCHAR* table[]; static const int table_size; }; // .cpp側 const WCHAR* MyClass::table[] = { L"aa", L"bbb", L"あ", L"c" }; const int MyClass::table_size = (sizeof table / sizeof table[0]); というのは可能だけど、この table_size を使って int a[MyClass::table_size]; とはできないね
と思ったら private じゃんか MyClass.cpp 内(というか MyClass::table の実体定義が見える場所)なら sizeof できるので、 private なら特に問題ないか
>>164 定義順によっては sizeof table はエラーになるよ(処理系によるかもしれないけど)
class 定義
変数定義
sizeof table
の順に並んでれば問題無いけど
class 定義
sizeof table
変数定義
の順に並んでいると sizeof table を解釈してる時には table のサイズが未定なのでエラーになる
そりゃそうでしょ
int main() { using namespace FooLib; return 0; } これはmain関数の中でのみ名前空間を有効にするってことでしょうか?
>>166 そりゃそうなんだけど、並び順で sizeof がエラーになるケースって珍しくないか?
>>169 別に
#include <iostream>
extern int a[];
int main() { std::cout << sizeof a << std::endl; }
int a[] = { 1, 2, 3 };
でもエラーになるで
根本的な理由はサイズが決まる前に sizeof を使ってる事
「使うための情報が揃ってない位置では使えない」が基本の C/C++ では
とりたてて珍しい事でもないっしょ
むしろ、class 内の関数定義内では宣言前のメンバも使える
って方が珍しい例だな
>>147 typedef WCHAR*(&WCP_R)[4];
WCP_R table;
Myclass():table(G()){};
WCP_R G(){static WCHAR*r[4]={ L"aa", L"bbb", L"あ", L"c" };return r;}
extern が有ったね 確かにクラス内の静的メンバも extern と似てるって言えば似てるからなぁ、実体はどっかに有るからって投げやりな態度が
>>171 普通に static メンバにすればいいだろw
>>168 こういう使い方もあるんだ。今度からはこうしよう。
クラス内で完結するテーブルなら無名名前空間にとじこめとけ
まあ、クラス内で定義されてる型を使ったり 配列のサイズがクラス内で定義されてる定数で決まる場合は無理だけどね
>>173 Gxx()を増やせばバージョン増やせます。デフォr[4]、時たま書き換え用r[4]など
配列をtypedefする男の人って・・
読みにくいだけだよ
配列がクラス化されてりゃよかったのに。 int x[10]; = array<int, 10> x; // あれ、どっかで見たぞこんなの
boostにあるで
某ゲーム機プラットフォームメーカーディスってんのか
こうしてみてみるとタイムアタックなのに息をするかのごとく const 付けちゃう所がC++中毒になっているんだなぁと痛感した。
2分切れないようじゃまだまだだな
186 :
183 :2010/03/22(月) 13:50:47
2分って言われるけど、アルゴリズムを考えながらタイピングして 俺はこの時間だったorz まあもう一度やればたぶん2分はぎりぎり切れるとは思う。
2分っての翻訳ミスって噂だけど
英語キーボードに慣れて 日本語キーボードがおぼつかない状態で すっげータイプミスしながらさっき適当にやったら 1:50弱だったが
暇だったから俺もやってみた 型チェックがあるから C++は3項演算子を使った解答ってあまり見つからんね 他言語ならすぐ出てくるのに。 ちょっと考えて思いついたのがこんな無理やりなやつ for(int i=1;i<=1000;++i){ char buf[256]; cout << ((i%15==0)?"FizzBuzz":(i%5==0)?"Buzz":(i%3==0)?"Fizz":(sprintf(buf,"%d",i),(const char*)buf)) << endl; }
別にコードゴルフしなくてもいいんだぜ?って思うw 素直に組めばいいのさ
%なしで5分でやってみようか
#include <iostream> using namespace std; int mod(int x,int y){return x-y*(x/y);} int main(){ for(int i=1;i<1000;++i){ if(mod(i,15)==0){cout << "FizzBuzz" << " ";} else if(mod(i,3)==0){cout << "Fizz" << " ";} else if(mod(i,5)==0){cout << "Buzz" << " ";} else{cout << i << " ";} } return 0; } 1:46秒
はて・・・何の相談?
俺つええでしょうか?的な?
すみませんc++のstringstreamのstr()の返値って stringへの参照でしょうかそれともコピーが返ってくるのでしょうか
ありがとうございます
>>145 そのくせCより遅いってwww
Cに追加した仕様は全部無駄ってことですよねw
C++はCより速い 開発速度的に あとstd::sort的に
実行速度的にはCとC++は同じだが、 可搬性を高めるようなC++的に良いとされる書き方があり、 その場合はトレードオフで実行速度または仕様の簡潔さを 犠牲にしているだけ。 追加した仕様が無駄という訳ではない。
202 :
デフォルトの名無しさん :2010/03/22(月) 19:28:57
D言語をどうぞ
D言語は別腹
C#はスイーツ
D言語はまだ調理中だろw
>>188 > すっげータイプミスしながらさっき適当にやったら
> 1:50弱だったが
待てよ、俺なんか普通に入力支援なしで#include <iostream>って打つだけでも一苦労だったぞ!
早すぎだろタイプミスしながらその速度はおかしいだろ
おれもおれも 関数定義の引数を打ち込みながらローカル変数何が必要かななんて同時に考えられんし。
>>208 俺は#include <iostream>は息をするかのごとく書けた。
病気だと思った。
かけてねえょ
JavaでいうScannerクラスのnextIntみたいな関数ってC++にありますか? 13 41 288 52 みたいにスペース(あるいはその他の区切り文字)で区切られて数字が並んでるときに 13,41,288・・・ と順番に取得していきたいのだけど,C++だと自分で書くしか無いのでしょうか。
>>211 sscanf(), stringstream
>>161-162 ありがとうございます
その方法がやりたかったことに近いです
勉強になりました
214 :
デフォルトの名無しさん :2010/03/23(火) 09:23:42
seekg の動作がいまいちわかりません #include <iostream> #include <fstream> using namespace std; int main(int argc, char *argv[]){ int i; string str; ifstream file( argv[1] ); if( !file ){ cout << "ERROR" << endl; exit(1); } while( file >> str ) {} file.seekg( ios::beg ); file >> str; cout << str << endl; file.close(); } 希望としては、このプログラムでファイルの一行目を抜き出したいのですが 結果として最終行が抜き出されます。ファイルシークができてない!? どなたかご存知方ご教授お願いします。
seekg(0,ios::beg)
>>215 それも試しましたが同じ結果でした・・・
//while( file >> str ) {}
>>217 確かにそうですが、一度最終行まで読み込んだ後にシーク処理を行いたいのです。
なにか他にいい方法ないでしょうか・・・。
こんな朝早くから愚問にお答えいただきありがとうございます。
>>218 file.clear();
file.seekg( 0, ios::beg );
>>219 ありがとうございます!希望通りの動作になりました!
mylib_1.so と mylib_2.so を混ぜ合わせて mylib.so を作りたいのですが、 どうすれば???
string配列のソートはよくありますが そうではなくstring自身をソートするのは可能でしょうか。 string data = "hoge"; とあったときsort(data)が"egho"を返すようにしたいのですが。 (つまりdataの中身をアルファベット順にソート) 一旦vectorに一字ずつ格納してsortといった手順になってしまうのでしょうか。
そういうのはlocaleに依存するんでー
普通にstd::sortすればいいじゃない マルチバイト突っ込んだときのことは知らないけど
A a;はいいのに A a();はエラーになるのはなぜですか?
>>227 間違えた
A a(); はAを返す関数a()の宣言だから
>>228 ありがとうございます。
A a();と区別させる方法は無いのなら諦めます。
>>230 組み込みでも標準ライブラリは一通り使えるけど、↑は極端な環境だね。
シングルチップマイコンで済ませるような 小さなシステムなら特に珍しくもないよ そもそもそういったシステムは標準ライブラリそのものの出番が少ない コンソールなんてないし、ヒープも定義しなかったりするからな
最近はDOSが組み込み呼ばわりされるからなあ。恐ろしい世の中だよ。
DOSが組み込み???
boostのis_classにある以下の記述はどういう意味があるのでしょうか? template <class U> ::boost::type_traits::yes_type is_class_tester(void(U::*)(void)); template <class U> ::boost::type_traits::no_type is_class_tester(...); 特にvoid(U::*)(void)は何を意味してるんでしょうか?デストラクタへのポインタ?
メンバ関数へのポインタ?
Modern C++ Designの2.7あたりを読むと幸せになれるかもしれない
type Class::*はtype型のClassのメンバのポインタだよ。 例えばClassの中身が以下になっていたとする。 struct Class{ int a, b; }; int Class::* memptrとした時、memptrには&Class::aや&Class::bを入れられる。 memptr = &Class::a; //memptrはClass::aを指す これがどういうことかというと、例えばClassのインスタンスを適当に作る。 Class obj; メンバポインタはClass::aとClass::bを区別なく動的に使用できる仕組み。 obj.*memptr = 10; obj.a; //10 勿論memptrに&Class::bも入れられるから、 memptr = &Class::a; obj.*memptr = 10; //obj.a = 10 memptr = &Class::b; obj.*memptr = 8; //obj.b = 8 この様な動作ができる。 メンバ変数に対して使えるならメンバ関数にも適用できる。その時の型の修飾がReturnType (Class::*)(ArgType);
もうあんまり覚えてねえなあ Uがクラスだったらメンバ関数へのポインタに変換可能性があるから yes_type返して、クラスじゃないなら変換可能性がないから 可変長引数側のno_type返して、メタ関数使ってsizeofで比較するんだっけか? 多分yes_typeかno_typeのどちらかが配列とかだったよな 標準ライブラリとかと同じでtype_traitsとか中身見ねえわ
241 :
235 :2010/03/24(水) 01:24:20
あー言い方悪かったです。 メンバ関数へのポインタは分かるんですが、void(U::*)(void)が構造体のどのメンバに引っかかって上の関数の呼び出しが優先されるのかが分からなかったんです。 struct Hoge{}; is_class_tester( (Hoge*)NULL ); // <-何でvoid(U::*)(void)が選択されるのか?メンバもないのに・・・
メンバがあるかどうかは区別されないだけの話
メンバがあるかを見ているのではなく、
関数のメンバポインタを取得する void(U::*)(void)という「形」が合っているかをチェックしている。
初めて目にした人は「どのメンバに該当したのか?」が気になるところだが、
コンパイラは単に「Uはメンバ関数を持つか?」だけを見ている。
…という説明をしても何を言っているかさっぱりだと思うが、
C++の型は
・charやintなどの予約語の型
・enum
・classとstruct
などのようなグループ分けがされていて、
「U::*」という構文が許可されているのはclassとstructのみ。
そのため、SFINAEの規則によってclass以外の型に対しては
>>235 の前者のオーバーロードは候補から除外される。
これで理解できないなら
>>237 か
>>238 の本を買って読むことをお勧めする。
というよりこういうことに興味があるなら読んでおくべし。
なお、よく考えれば分かることだが、void(U::*)(void)という型は
Uがそのようなメンバ関数を持っていなかったとしても文法的・意味的に「正しい」。
単に、正規の手段でその型に代入できる、意味のある値を生成することが不可能なので使い道がないだけ。
別人ですが、
>>243 > これで理解できないなら
>>237 か
>>238 の本を買って読むことをお勧めする。
> というよりこういうことに興味があるなら読んでおくべし。
俺は普通にC++を使いたいだけで、最低限の気をつけるべき事とかは
勉強するけど、変態的プログラミングは自分ではしたくない!と思っています。
こんな私はそこは勉強しなくても大丈夫でしょうか。
読み書きすることがないなら別にいいよ
大丈夫かを人に問うのではなく、自身がよいと思えばそれを貫けばいいだけ。
国語でいうなら語彙力が増えるというのに似ているかと やたらと難しい言葉を使いたがる人がいるのも似ているかと うまく使えば冗長な文章がスッキリまとまるところも似ているかと
完成したと思った後に無駄なところを直して 無駄がなくなるまで直すと一番無駄がなくなるんだよな。
そして時間を無駄にしましたとさ
質問です 大学の教養でJAVAをやった程度の初心者なんですが、C++を学びたいです テンプレのamazonのリンクは全部英語ですが、日本語の本でお勧めなのないですか?
JAVAがつけるならeffective c++でc++の作法を学べばいいんじゃないか。
すみません ちゃんと翻訳もあったんですね java使えるって言ってももう何年も前だし、やったのも大学一年生程度(しかも評価甘いし、やること少ない)です わかるようなもんでしょうか? 具体的には関数とか定義して、、、ての程度しかわかりません
253 :
252 :2010/03/24(水) 19:01:41
初心者丸出しですみません ググってたら翻訳者の方?のページがあって各本の目次と解説がありました 多分effectiveではわからないからもっと簡単そうなこれならわかるC++から始めてみます 質問にのってくれてありがとうございます
なら入門書からやったほうがいいな。
構造体をtypedefしたものは新たに型を導入するので良いんですが 型の別名を与えるようなtypedefの使い方って プログラマの意識の問題だと思っていいんでしょうか たとえば何かをメートルで返す測量関数があって typedef int METER; METER measure(){return 1; /*仮の実装*/} int n=measure(); //return typeと型が違うが、実態はintなので何も言われない
typedef std::vector<int>::iterator iterator; みたいに長い型名を短くするとか uint32_t みたいに環境が変わっても対応できるようにするとか テンプレート引数を使った型を typedef して外部からも使えるようにするとか 後から型を変えられるようにするとか 同じ型を使うことを強調したいときとか そんなところ
>>256 > uint32_t みたいに環境が変わっても対応できるようにする
>>255 が懸念しているのは、
uint32_t foo;
int bar = foo;
とあった時に、環境が変わったときに初めて問題が表面化することを避けられないということなのでは?
強い型付けじゃないから 自分で気をつけるしかないのよね 残念ながら
確か D だと typedef と alias の2つがあるんだよね
strong typedefをお待ちください
なるほど。0xに期待します 後、Dには固めるテンプルを振りかけたいです
テンプレート関数のデフォルト引数いいね
template<typename T> class MyClass{ 〜〜〜〜 }; こんな自作クラスには、T型を取得できるようにするtypedefを用意するなどといった コンセンサスはありますでしょうか。 template<typename T> class MyClass{ 〜〜〜〜 public : typedef T value_type; }; などです。 文化的なコンセンサスなどがよく分からないので こちらのスレで質問させていただきました。 よろしくお願い申し上げます。
>>263 そんなコンセンサスは特にないと思う
コンテナや関数オブジェクトなんかはSTLやboostに倣うべきだけど
そうでなく、必要ないならつけない方がいいと思う
正反対の意見が続いちゃったけど
そういうコンセンサスを明示的に指定できる機能が 言語仕様に取り込まれるかと思いきや延期されたので STLにならってvalue_typeでいいんじゃね
みなさんありがとうございます。 まあ指定しても損はないと思うので指定しておくことにします。 ありがとうございました。
>>267 君はそれに対して懐疑的な意見を持っているように読み取れるが、むしろそれは推奨されている手法である
じゃないの?
270 :
267 :2010/03/24(水) 23:05:27
>>269 あー、そう言う意味で「むしろ」って言ったのか。
スマソ!
俺が悪かった。
ありがとう。
STLコンテナ準拠ならvalue_type付けとくべき。 それ以外もしくは要素の型でないのなら、traitsで部分特殊化を作るしかない。
traitsの仕様について、英語でも良いのですが "簡単に"まとまっている所ってありますでしょうか。
引数が同じで戻り値だけが異なる関数はオーバーロード出来ないと思ってたんだけど、
どうしてこれはエラーにならないんでしょう?
http://codepad.org/hhWRunbl Factory::create_int();やFactory::create_Hoge();みたいな感じで解釈されるから?
>>273 これのどれとどれがエラーになりそうだと思ったって事?
275 :
272 :2010/03/24(水) 23:29:15
あっ忘れてた。createメンバ関数の部分です。 同名だからダメかなぁと思ってた。 class Factory{ public: template<typename T> TFoo<T> create(){ return TFoo<T>(); } Foo create(){ return Foo(); } };
276 :
274 :2010/03/24(水) 23:35:15
とりあえず int main (int argc, char * const argv[]) { Factory fac; TFoo<Hoge> hoge = fac.create<Hoge>(); //@ A Foo foo = fac.create(); // B return 0; } Hoge //@ TFoo //A TFoo// B この対応になっていることは おわかり頂けるだろうか。
277 :
272 :2010/03/24(水) 23:49:21
1がTFoo<Hoge>のメンバ変数になってるval_(Hogeクラス)のコンストラクタで出力されて、 2がTFoo<Hoge>のコンストラクタで出力される。 3でTFoo<int>のコンストラクタで出力される ですよね?
278 :
274 :2010/03/24(水) 23:55:41
>>277 そうです。
それが分かるんならもう分かるんでね?
テンプレートの方はcreate<T>って名前で(Tしだいで
名前が変わりうる。)、非テンプレートの方はcreateって名前だと
思えば。
279 :
272 :2010/03/25(木) 00:13:25
クラスのメンバ関数は同名だとダメだと思い込んでました。 言われてみれば、グローバル名前空間に作ったテンプレート関数は使い回してたのに、 クラスだけは変に解釈してたみたいです。 おまけにテンプレの勉強用にと買った本の最初の方に疑似コード付きで乗ってたし、、、 ありがとう。よし、すっきりしたから風呂入って寝る。
280 :
274 :2010/03/25(木) 00:13:25
君の心配はごもっともだが
『C++の仕様上 認められています』
と断言して、
納得いかなくてもそう思ってもらうしかないような。
ttp://codepad.org/PYlvK3e2 このコードでは勝手に引数の型を見てcreateという名前を持つテンプレート関数と非テンプレート関数を
どっちを呼び出すか決定されるけど、
この引数がなくなっても同じ。
ttp://codepad.org/bFMt364W どっちがよりマッチするかと言えば非テンプレート関数の方だから
非テンプレート関数ばっか呼ばれる結果となる。
ただし明示的にテンプレート引数を指定したらそりゃそっちが呼ばれるでしょうよ。
std::traitsクラステンプレートなんてあるのですか?
>>281 traits はイディオムやパターンの類です
型世界のストラテジーパターンみたいなもん
std::numeric_limits なんかも traits の一つです
書庫に複数対応しているDLLないですか。 解凍とリスト取得できるのでいいんですが。 外国製が良いです、
国籍変えて自分で作ればおk
285 :
283 :2010/03/25(木) 13:52:20
総合アーカイバープロジェクトのDLLってリスト取得がえらくかかるのが 多いです。 速くとれるやつが良いんですが、
整合性とかcrcとかいらないので、ヘッダ情報のみ読んで直ぐリターンするやつが良いです
スレタイ読んだか?
288 :
281 :2010/03/25(木) 16:49:40
>>282 ありがとうございます。
iterator_traitsとかその辺をまとめて呼ぶ言葉なのですね。
template <class X> void raw_swap(X &a, X &b) { memory_swap(&a, &b, sizeof(X)); } 代入とかならメモリだけ移してもダメなのは分かるんだけど swapならメモリ交換するだけでいいのでは?
>>289 メンバー変数へのポインタを外で保持している可能性があるからダメ
引数に与えたクラスがXの派生クラスの可能性がある。
NULL文字を途中に含む文字列・・・というかバイト列(const char[])を 扱いたいのですが、std::stringで扱えますか?
vector<char>を使いましょう
okだが関数の引数がchar*なら &s[0]を渡してで止まる。
>>292 へんなの教えるな。それはいろいろとC++な手間かかるうえに
連結とか人間の手間も増える
std::stringはヌル文字含めた気がする ポインタ取りたいときは c_str() の代わりに data() 使うといい
バイナリ文字列の注意点は入出力だけ。 あとは違いなし。 charに0付近の値を入れたら駄目とかは無い。
std::string str; str += "hoge\0piyo"; だけじゃ hoge しか追加されないから 扱いやすいかというと微妙な所はあるが 終端をちゃんと指定してやれば扱えたはず
s+=string( ch, 10);
string str(pch, pch + N);
300 :
291 :2010/03/25(木) 23:06:19
ありがとうございます。 なるほど、ちゃんとしかるべく気をつければOKなのですね。
自分でバイト列を管理するクラスを作るのも 良いかもしれないと俺は思う。 ただバイト列を多用するならだけど。
class A { private: static const int TEISU = 10; static const int TEISU_ARRAY[2][2] = { { 1, 2}, { 3, 4}, }; }; TEISUはコンパイルエラーにならないのにTEISU_ARRAYはコンパイルエラーになります。 どうなってますか。 ちなみにTEISU_ARRAYをclass A{ }の外に出したらコンパイルエラーになりませんでした。
現状ではその書き方で初期化できるのはstatic const 整数だけ C++0xをまたーり待ちましょう
zlib って誰が使うんだ。
0x7EがJISではオーバーラインだったなんて知らなかった。 昔のC++はデストラクタが  ̄MyClass() {}; なんて表示されてたのかな。
そのころはC++なかったな。
PC-9801でも既に上付きの波線状態だったような気が
Macのターミナルでは設定によっては ̄で表示される
>>304 Changelog見たけどかなりの更新量だなあ…
multi_array_ref は既存データの配列が multi_array インタフェースを提供するよう適合させる。 multi_array_ref は渡されたデータを所有しない。 これってどういう意味ですか?
multi_array_ref と multi_array は使い方が同じ。 ただし multi_array_ref はデータを参照で持っているため、メモリ領域を持たない。
>>306 何気にそれでも大しておかしくないよな。
もうちょっとデストラクタの記法もどうにかならなかったのだろうか。
0x7Eってデストラクタ以外にも使ったっけ?
ビット演算かなんかの単項演算子で合った気がする。
>>313 ~はnotの意味だから逆コンストラクタであってると思う・・・・苦しすぎる
IPAゴシックフォント使ってるけど~がオーバーラインだな
>>314 ああ、否定か。
苦し紛れに適当に空いている文字を付けたのかと思ったよ。
>>314 !MyClass() {};
…こっちも苦しいな
コンストラクタが+で、デストラクタが−にならなかっただけでもよしとするか?
319 :
313 :2010/03/26(金) 22:57:49
>>318 案外いいな、それ。
俺のセンスだとそっちに一票入れてしまう。
C++なんだから++と--でどうよ
notの意味で~使ってたのかw よく考えたもんだな
>>317 C#のファイナライザがそれだったような
いや、C++/CLIだ。C#は~
>>324 switchよりもハッシュテーブルとか仮想関数を使うけどな。
>>326 ハッシュテーブルとか仮想関数の守備範囲と
enum&switchの守備範囲は
そんな同じじゃないと思うが。
変数宣言 甲int *a; 乙int* a; 丙int * a; どれがいいのでしょうか。 どれも同じ意味なのですが、 int *a,b,c; と書いたとき、aだけはint *型、bとcは普通のint型になります。 もし乙だと int* a,b,c; と書いたとき非常に勘違いしやすそうに思います。 折衷案の丙も int * a,b,c; なんか気持ち悪いですよね。 ただ、同時に宣言する変数が1つだけの場合、型はintではなくint *型なのだから int* a; も捨てがたいです。 どれが良いとか推奨とか有名人が勧めていたとかありますでしょうか。 ポインタ*でなく参照&でも同じ事だと思いますが。
>>328 乙に一票
それぞれのメンバにコメント書くために複数同時宣言はしない。
*まで含めて型として扱うし
int b,c,*a;
331 :
328 :2010/03/27(土) 00:01:33
> int b,c,*a; 発想の転換ですね。 ちなみに私は乙派です。 int* a; MyClass& obj;
あくまでもネタですよ 同じ行に書かないというのが前提で、それぞれは甲で記述します。 キャストの際もstatic_cast<int *>と甲、または丙方式です。
禿曰く、 「俺がイチから言語を設計していたら、ひとつの宣言文で複数の変数を宣言できるようには、絶対にしなかった」 出典はD&E
問題は禿が優れたプログラマであるかどうかを知らないということだ。 Knuth先生がそういうなら信じる
Knuth先生は優秀すぎるよ 彼が証明する事実は素晴らしいが 彼のアドバイスは天才の世迷い言だと受け止めるのが凡人の生きる道 文芸的プログラミングを誰が実践できるんだ
俺も自分で書くときは乙形式だな constも前と後ろ両方の書き方あるけど、 A) const int* B) int const* 普段Aで書いてるけど、多重ポインタになってるとき int *const * とかはBの方がいいのか?と思ったりもする。
人が見るソースだとパッと見でわかりやすいようにtemplateつかってしまうな。1行に1変数で
漏れは甲 絶対譲らん
>336 それって int const* と int *const の意味が違うのを判って言ってるんだよね?
const int x, *p; int const y, *const q; constなint型の 変数x constなint型の ポインタp int型の constな変数y int型の constなポインタq でいいのか?
アスタリスクは型の識別子じゃなくて変数の識別子に対する修飾だからね。
>>340 const int x;
int const x;
は一緒。
const int *p;
int const *p;
も一緒
const int * const p;
は違う
>>340 そこは
int型の定数y
intへのポインタ型の定数q
とかに。
const int * const p; 使った事無い これが必要なシーン教えて
>>344 static int const foo[] = {1, 2, 3, };
int const * const p = foo;
必要と言うより、安全策だな。
typedef const char* LPCSTR; const LPCSTR Hoge = "Hoge"; こういうのはよく使う これは const char* const Hoge = "Hoge"; と同じ意味
factory使うと Product*const* getAll(); みたいな二重ポインタ返すのはあるな。 一番外側にconstはうっかり防止だな。
*const を使わない頻度は 普通の const int を(グローバルな定数宣言ではなく)自動変数として使わない頻度と変わらないだろう ポインタ属性とは関係ない気がする
ポインタのconstはワンウェイクラッチみたいなもん
ワンウェイクラッチが何かわからないので ワンウェイクラッチをcons修飾みたいなものと考えることにする。
ワンウェイホイールなら分かるけど・・・仕組みを考えると爆発するけど
one wake latch ?
このスレでスマポ作ってた人はどうなったんだろう
彼はBoostになったのさ。
俺もスマポ自作したことあるが、必死に考えぬいてすこしずつ効率を上げるんだけど boostのソース見るとすでに実装されてたり余裕で上を行かれてたりするから虚しくなってやめた
スマートポインタなんぞ不要。
全部boost使えばいいんだよboost
boostとかすごく便利なんだけどここまでくるとc++である必要があるの?と思えてくるな
C++のような直接的に記述ができるのはほかにないし。
新しい言語設計して布教したほうが未来があるとおもう
おもう自由くらいは許してやる
C++の利点って主に実行速度でしょ? Boostでそれが損なわれてるわけじゃないから良いんじゃないの
>>362 実行速度に加えて拡張性だろう。
文字列クラスなんか組み込み型なのかと思えるほどのように使える。
C++の利点は生産性が必要な部分は生産性を、 低レベルな実行速度が必要な部分は実行速度を、という風に特殊化できるところだな。
C++動作が明確なのも大きいな。 GCがある系だとデストラクタが呼ばれるタイミングが分りません。呼ばれないかもしれません。じゃあこまるし。
OCamlやF#にもあるように、実はパラダイム的には関数チックな言語の方が GCは向いているかもしれん。
向いてるというか無いとやってられないかと
つまりC++を関数チックに使えということですね?
>>367-369 なるほどな、コンパイル中のtemplateの展開中のメモリ管理を気にする人なんていないし。
370 じゃない俺が妄想。 つまり C++ を関数チックに使えということですね? →template メタプログラミングは関数チック →関数チックだと GC 無いとやってられないかと →でもコンパイル中の template の展開中のメモリ管理を気にする人なんていないし
GCとコンパイル中のメモリ管理がどうつながるのかわかんね
370は皮肉なんじゃねーのかよ
>>373 C++テンプレートは事実上の関数型(インタプリタ)言語
コンパイルはテンプレート言語の実行
えっ?
Lisp系の処理系作ってみた事ある人はわかると思うけど GC付けないと色々大変
それはリストを処理するからであって
bzip bz2の書庫内容をよみとれるC/C++のソースコードありますか。 Tar32DLLのは遅いんです。復元は出来なくても良いです。
書庫標準のライブラリに非依存のヘッダかフッダを 読み取るソースがあってもいいもんだがなと思う。
ヘッダーとかフッダーとか語尾にーを入れない奴って深い意味は無いが みんながそうキーボードで打ってるからって理由だろ。 なんでみんなそんなに人に合わせるの? 自分の意思は無いの? 理由を調べようとはしないの? そんな生き方間違ってるとはおもわないの?
>>382 Tar32DLLはそれを利用してるんです。それが遅いんです。
復元・圧縮機能いらないのでファイルリストだけ取得したいです。
実際そのアルゴリズムが遅いの? ファイルIOが遅いとかじゃなくて
>>384 だからそいつを解析すればいいじゃん。そんなことも判らないの?
>>384 ファイル「リスト」っていってるってことは.tar.bz2だな?
Tarはフォーマット的に、全部読まないと(=復元しないと)全てのファイルは分からないはず。
ああそうかtar.bz2か。
たぶんですがTar32DLLの呼び出し方が原因かと。 ファイルIOじゃないと思います。 書庫サイズ40Mでファイル名を取得するだけで遅いです。 解凍と書き込みはしてないです。
そうなんですかヘッダ・フッダとかはないんですか。サンクス。全解凍しないと駄目なのか。
>>387 .tarは必ずしもそんなことはないが、.tar.bz2だと解析の前にbzip2の展開を行なわないといけない。
確認しました tarにはヘッダがありませんでした シーケンシャルでロードするか、ファイル情報が書き込まれてそうなあたりを試行錯誤して 探すしか無さげ
速いのならソースを見比べてみては?
古いソースして置いてないです。非対応のやつ
bzip2関連のソースもあるようだけどどういうことだろう
FindNextが未完成 つねに失敗
圧縮アルゴリズムって権利にうるさいらしいけど 開発してる人は大変だね。
138
『Exceptional C++』が難しいと嘆いた者です。
ttp://www.amazon.co.jp/dp/4894712709/ の
<A>p34の2.に、
> 例外を投げた際に代入しようとしていたTオブジェクトの値が
> 変更されていないことを保証しなければならない。
<B>p43の ・ の4つ目に、
> コピー先のオブジェクトの状態が変更されないことを保証するため
とありますが、
これは
T a, b;
a=b;
とすると両方ともbが変更されないことを保証すればいいってことでしょうか。
<A>はどっちにも読めますが文脈的にはbの不変性のことを、
<B>は反対の意味に読めますが文脈的にはbの不変性のことを
言っている様に思います。
つまり、<B>は原著のミスまたは訳者の誤訳でしょうか。
よろしくお願い申し上げます。
>>399 たぶん君の解釈の間違い。
読んだ限りではA,Bとも
「a = b; が例外を投げたとき、aの状態が変更されない」
すなわち「強い保障」をすべきという意味。
つまり、例えばT::operator=()が ↓こういう実装になっていてはいけないということ。 T::operator=(T const& t) { // 1) this.m = t.m など、何か状態を変更する処理 // 2) 何か例外を投げるかもしれない処理 // 3) 何か処理 } この例だと、2)の処理でもし例外がthrowされると、 operator=を抜けた先でthisの状態は既に変更されている。 すなわち「強い保障」がされていないということになる。
402 :
399 :2010/03/29(月) 21:26:01
>>400-401 ありがとうございます。
教えていただけた内容を考えながらもう一度そのセクションを
読み返してきます。
もう一つお伺いしたいのですが
p52の真ん中やや下ぐらいのところに
Stack& operator = (const Stack& temp)
{
Swap(temp);
return temp:
}
とありますが、これは
Stack& operator = (Stack temp)
の間違いでしょうか。
× return temp: ○ return *this; それはともかく、 Stack::Swap()のシグネチャはSwap(Stack&)だから、そのコードだと Stack& operator=(Stack temp)でないとコンパイルエラーになるね。 それは普通に本文のミスだろう。
めんどくさいときはこれで多くのケースで代入の強い保証が解決出来る。スワップ最強 Hoge &operator = (const Hoge &other) { Hoge(other).swap(*this); return *this; }
405 :
399 :2010/03/29(月) 23:30:35
>>403-404 ありがとうございます。
なんか頭おかしくなりそうです。
みなさん全員、こういった難しいことを考えながら
クラスや関数を書いているのでしょうか。
C++はそういう作法を覚えるまでが大変だから新規に勧めづらいんだよな
tar.bz2の復元ルーチンはどこにありますか。 bz2したのをtarするのは時間くいます。 一つ一つやるのが良いんです。
>>392 tar は 512 バイトブロックで
ヘッダかデータだろ。
512バイト単位でシークしてヘッダならそのファイル名を
抽出して、そのあとサイズを 512バイト境界でスキップ
していけばリストは比較的簡単に作れると思うが。
>>409 スレ違い。 .tar.bz2 作ったやつに頼め。
tar32dllつかっとくわ
それにしてもunix使うやつは、tar***というくそ仕様の書庫使ってるな
シーケンシャルのテープとかの保存しか考慮して無いだろ。 zipのようにランダムアクセス出来る方が便利なのに。
圧縮率の問題でしょ。 辞書を共用出来る形式の方が圧縮率が高い。 WindowsでもCABやRARなんかはその手の形式だが やはりランダム操作は出来ない。
つーかtarってまんま Tape ARchiveなんだが。
ソリッドでエラー出たらデータ消えるぞ。 こんな古典的書庫を使い続ける意味わからない。 テープなら素直に解凍・書庫できるメリットはあるけど。 いまテープにTar使うやつの方が少数だろ。別のフォーマットに移行しろよ。
zipがいいならzip使えばいいだけじゃんね
zipの方が書庫のままで写真集を見るのに便利 rarは遅くていかん
420 :
399 :2010/03/30(火) 09:46:34
>>406-407 ありがとうございます。
ttp://codepad.org/XOl4IAmh このコードの様に理解しているのですが、
T型が例えばstd::stringのように動的メモリ確保などの事情で失敗する
可能性が考えられる場合、
CopyConstructorと代入演算子を例外安全に実装できません。
どうすれば例外安全かつ例外中立に実装できるでしょうか。
よろしくお願い申し上げます。
>>420 コピーコンストラクタは引数3つのバージョンと同様の実装でいい。
あとはメンバそれぞれに swap() を呼び出す swap() を用意して、
swap() が例外を投げないという前提の下、
>>404 を使えばいい。
例外を投げない swap() を前提にできないのなら、メンバをまとめて
ポインタで持つようにする。 pimpl の形。
http://www.gotw.ca/gotw/059.htm
標準ファイル入出力で、badとfailの差ってなんでしょう? 重度・軽度って解説してる所を見つけたんですが、具体的にどうなのか分からず・・・。
>>420 template<class T> class MyClassTemplate
{
T mem1, mem2, mem3;
public:
MyClassTemplate() : mem1(), mem2(), mem3() {
}
MyClassTemplate(const T& arg1, const T& arg2, const T& arg3) : mem1(arg1), mem2(arg2), mem3(arg3) {
}
~MyClassTemplate() {
}
MyClassTemplate(const T& other) : mem1(other.mem1), mem2(other.mem2), mem3(other.mem3) {
}
MyClassTemplate& operator = (const T& other) {
MyClassTemplate(other).swap(*this);
return *this;
}
void swap(MyClassTemplate &other) {
swap(mem1, other.mem1);
swap(mem2, other.mem2);
swap(mem3, other.mem3);
}
};
これでいいよ
>>422 fread(), fwrite() などのストリームアクセス自体が失敗するようなのが bad
アクセス前後の数値 <-> 文字列の変換が失敗したとかいうときは fail
>>424 ファイルオープンに失敗などはbadなんですね。
ありがとうございます。
相互に変換かのうな型A,Bがあったとして コンストラクタで変換するのかキャストで変換するのか どっちがより良い方法でしょうか?
>>426 安全に変換できるように作られてるなら、キャストしないでいい。
どうにかして変換できる、っていうレベルならキャストで注意を引き付けた
ところにコメントで説明を加えるのがいい。
B convertAtoB(A)みたいな関数を作るのが一番いい
429 :
420 :2010/03/30(火) 21:30:11
>>421 >>423 ありがとうございます。
例外を投げないswapというのは、普通 要求していいことなのですか?
つまり、
「俺のクラスのswapは例外なげるかもよ?」とか同僚が言ってきたら
「ふざけるな作り直せ」と言っていいレベルなのでしょうか。
431 :
420 :2010/03/30(火) 21:35:13
>>430 ありがとうございます。
今回はpimplを使って例外安全を得ようと思います。
今度そう言われたら「ふざけるな作り直せ」と言うことにします。
ありがとうございました。
そうなの? マルチスレッド対応したクラスなんかどうなるんだろう
boost::variant とかは swap が例外を投げ得るyo
>>428 B::FromA(a)
みたいなのよりよいの?
swapで例外投げるとかどんな状況だ?
>>435 嫌がらせ
とは言わんが、例えば
std::stringのswapを単にstd::swapの通常の実装でやっちゃったら
例外を投げ得るよね。
>>433 マジ?
今ソース見てみたけどそうは見えないですよ?
437 :
433 :2010/03/30(火) 23:52:50
ごめん勘違い。 variant みたいのを素朴に実装すると例外が出ちゃうから、 boost::variant では例外を投げないようにする為に それなりに負荷がある処理をしてますよ、という話だた orz
>>437 variantは異なる型の間でswapを実現しないといけないからか?どうやってるのか想像がつかないな。
よくわからんけどBit列をまるごとスワップしちゃえばいんじゃね?
1.42のboost::variantのswapを見てみたが、 ライブラリベースでムーブを実装し、それでswapを実装しているようだった。 ムーブの中身までは見ていない。
437は不正確な表現かも。 例外を投げないようにするのが目的というより、中身が never-empty である ことを保証するため、だった気がする。
boost::optional<T> とか variant<T,U> とかは T, U のコピーコンストラクタ が例外を投げるなら、swap の中から例外が投げられる可能性はあるよね? swap 自身が投げる訳じゃないけど。
>>442 > テンプレート引数のコピーコンストラクタが
> 例外を投げるなら、swap の中から例外が投げられる可能性はあるよね?
何を当たり前の話をwww
全員pimpl以外認めないとでも言いたいのか?
メタプロでswapメンバ→swap関数(ADL)の優先度でやればめったに間違いは起こらない
一般的にswapが例外投げない事になってるなら 逆に一般的に例外投げない事になってる関数を教えて。
move
入門書読み終わって、載ってるソースは大体分かるようになってきました 中級にレベルアップしたいんですがどういう本とか学び方がいいんですかね プログラミング学んだのは就職に有利になるかな?とか、プログラミングできるなんてすげぇくらいの 気持ちで始めたので特に目標とかこれができなきゃならないとかないです
EffectiveC++
自作クラスをpimpl idiomで実装してpimplはすごいと驚きました。 そこで、とある自作クラステンプレートをpimpl idiomで実装しようと思ったんですが、 pimpl idiomとクラステンプレートって相性悪いですか?
450 :
447 :2010/03/31(水) 18:14:18
すみません 推薦書スレのテンプレ参考にします effective C++も考えてみます 参考に聞きたいのですが上級者の皆さんはどういう手順でうまくなったんですか?
>>447 > テンプレ参考にします
最新版じゃないことがあるから重々ご注意を!
例えば、かの名著『Effective C++ 』の最新は
Amazon.co.jp: Effective C++ 原著第3版 (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES): スコット・メイヤーズ, 小林 健一郎: 本
ttp://www.amazon.co.jp/dp/4894714515/ これだから。
453 :
449 :2010/03/31(水) 18:18:11
>>451 なんかexportを使わない限り
実装とインターフェースの分離でコンパイル依存性の軽減が出来る!
というメリットが消えますよね。
ところがexportの廃止が決定されたとのことで。
うーん。
454 :
138 :2010/03/31(水) 18:20:40
>>453 型消去的な使い方とかコンパイルコスト以外の利点もいくつかあるだろ
456 :
447 :2010/03/31(水) 18:32:16
すみません 推薦書スレのテンプレ参考にします effective C++も考えてみます 参考に聞きたいのですが上級者の皆さんはどういう手順でうまくなったんですか?
457 :
453 :2010/03/31(水) 18:35:15
>>455 まあ確かに、pimplにする価値はそれだけでは無かったですね。
458 :
447 :2010/03/31(水) 18:35:36
space key押してたら二回入力されちゃったorz わかりました 第三版見てみます この前入門書買いに本屋に行ったんですがC系統の本は少ないですね 少なくともジュンク堂だと 立ち読みしたいけど無理かな?
書かなきゃうまくならない。 不具合の直し方とか本には書かれてない。 書こうという気にならないのは向いてないということなのかもしれない。
461 :
452 :2010/03/31(水) 18:50:52
>>458 ロベールの部屋
ttp://www7b.biglobe.ne.jp/~robe/ このサイトのC++の内容ぐらい分かる?
もし分かるならEffective C++は文句なく買いだと思う。
Exceptional C++が理解できればEffective C++は不要になりうるけど、
そのEffective C++が理解できればってところが難解だから
やっぱりEffective C++を今買っても良い。
目から鱗だよたぶん。
464 :
460 :2010/03/31(水) 19:02:11
俺には誤爆にしか見えんが。
>>459 > 書こうという気にならないのは向いてないということなのかもしれない。
書こうという気にならない人なんてこのスレにいないだろ
書くものがはっきりしてるなら漫然とした質問なんかしねえよ
466 :
458 :2010/03/31(水) 19:19:35
>>461 ちょっと目を通しましたが、自分の現在の能力として入門書一冊だけなので、
言うならば幅が狭いというか、知ってる関数・ライブラリとか、例が少ないと自覚しました
どうかな?多分、バン!とソース出されてやっとわかるかどうかくらいです
仮想関数とかテンプレートとか、本当に簡単なソースで習っただけなので自分で応用は効かせられないレベルですね
こういう場合effectiveに行っていいんでしょうか?
C++だと入門書一冊程度では何も知らないと言っていいレベル
468 :
452 :2010/03/31(水) 19:44:19
>>466 > こういう場合effectiveに行っていいんでしょうか?
それはまだ早いなぁ。
C++は本当に気が狂ったような言語だから
『Effective C++』も意味を理解するにはそれなりに知識と多少の経験が必要になる。
どーすっかな、『Effective C++』未満の難易度で適切な本が思いつかない。
みんなだったら何 すすめる?
>>466 本を何冊か読んだだけでプログラミングの勉強をした気分に
なってはだめ。
本1冊読んだなら、その知識を使って、なんか作れ。
最初は電卓みたいなのとか、メモ帳みたいなのとかでもいい。
まて、GUIが必要って段階でそのお題は微妙じゃないか? C++のソースコードの一部を受け取り文字列リテラル化するものとかどうよ? int main(){ タブstd::cout << "hoge"; タブreturn 0; } と記載されたファイルを受け取り "int main(){\n\tstd::cout << \"hoge\";\nreturn 0;\n}\n に変換するとか。 簡単すぎてつまらんか。。
コンパイラ構成論 を見ながらC++に翻訳しながら自前パーサー書きあげればオブジェクトの有難味とC++特殊性が判る
Boost本を買って、読みながら一通りサンプルコードを弄ってみるとか? 使うだけなら難易度はそこまで高くないし、 実装を知りたいと思い始めたら立派な変態候補生。
473 :
458 :2010/03/31(水) 19:58:09
みなさんありがとうございます 確かに実践力があるかと言われれば危ういところもあります メモ帳の簡単なやつは・・いけるかな?自信ないです 僕が買った入門書はとりあえずコンパイルと実行してみよう!みたいな乗りであまり深くはやってないです そのロベールの部屋なりで経験値あげて何か作ってみます
>>473 ロベールの部屋は入門書のWeb版みたいなものだから
あまり新しい発見はないかも。
メモ帳の簡単なやつとか、GUIライブラリを使わなきゃならなくなるから
果たして意味あるのだろうか。
475 :
138 :2010/03/31(水) 20:05:28
『Exceptional C++』
ttp://www.amazon.co.jp/dp/4894712709/ のp69の下部で
^19^ ^22^ ^21^ ^23^ ^20^
とありますが、このうち
" "
^21^
でどうして例外が発生する可能性があるのか理解できません。
(例外に関連したコードパスの文脈なので、例外が発生するという意味だと解釈しました。)
19-20 22-23
は本文に解説があるのですが、21だけは解説がありません。
どなたか教えてくださいませんでしょうか。
よろしくお願い申し上げます。
筆者にメールしろ
>>475 同頁の 6. に書いてあることじゃないの?
(operator== は operator+ に読み替える)
478 :
475 :2010/03/31(水) 23:28:42
>>477 ありがとうございます。
なるほど、暗黙の型変換が起こった場合に一時オブジェクトの生成に失敗して
例外が投げられると言うことですね。
479 :
138 :2010/04/01(木) 00:02:32
どなたか
>>454 にもお知恵をお貸しくださいませ。
よろしくお取り計らいください。
すぐあとに書いてあんだろうが 1000回読んでから質問しろ
先ず一回通して読め。 話はそれからだ
482 :
479 :2010/04/01(木) 07:43:20
>>480 すみません
やっぱり場所が分かりません。
何ページなのでしょうか?
>>482 リンク先のサムネイルがエンジニアのための文章術再入門講座になっているのですが、どうしてですか?
巨大テキストファイルのソートプログラムありますか。
はい。
例外でstd::exceptionの派生クラス全てキャッチする場合、 throwする関数ではローカル変数を渡しても問題ないのでしょうか? VCではnew、deleteで渡してたようだったので気になってます。 class myex : public std::exception {}; void func() { myex ex; throw ex; <<一時オブジェクトが作られる? } void main() { try { func(); } catch(std::exception &ex) <<不正アクセス? { cout << ex.what(); } }
参照キャッチで良い
>>486 new deleteで例外を渡すのはよしたほうがいい
>>487 問題は無いのですね。ありがとう。
ということは例外クラスは全部参照にしたほうがよさそうですね。
>>488 可能な限りnew deleteを使わないようにしておきます。
ありがとう。
>>490 キャッチ側で確実にdeleteする必要がある。キャッチ側に責任を負わせ、それを間違いなく確実に記述するのは難しい。
はっきり言って使うべきじゃない。
昔のMFCがnewして投げてたな そのためにtry_catchも専用のマクロが定義されていたはず
493 :
479 :2010/04/01(木) 20:52:23
>>483 環境依存だと思います。原因は不明です。
こちらの環境ではクリックするとamazonのExceptional C++のページに飛びます。
>>480 > すぐあとに書いてあんだろうが
すみません分かりません。
p52の話でしょうか?
すぐあととはどこでしょうか?
ことなる型の関数ポインタの配列を作る方法ありますか。
例としてこういうやつです int a(){} int b(int){} char c(){} int main(){ void (*fnc[])() = { a ,b , c }; }
ありません。 struct interface_type{ virtual void apply() = 0; virtual ~interface_type(){} }; struct wrapped_a : interface_type{ virtual void apply(){ a(); } }; struct wrapped_b : interface_type{ virtual void apply(){ b(int()); } }; struct wrapped_c : interface_type{ virtual void apply(){ c(); } }; interface_type *ptr[] = { new wrapped_a, new wapped_b, new wrapped_c }; とでもしてください。
サンクス
union使えばいいのでは?
結局うまくいかなくて配列・ループにしないで 全部展開したやつをそのままソースに乗せました。
C++で処理系依存でなく算術シフトを行う方法はありますか
std::vector<bool>っていうのを使うといいらしいですよ!!
504 :
501 :2010/04/02(金) 12:42:44
503は私宛でしょうか vector<bool>を調べてみましたがflipで反転は出来るものの シフトにあたるようなオペレータは特に定義されてないように思えます 自分で実装しましょうとかそういう話ですか?
負の数を2の補数にするかどうかさえ自由なのに、 処理系を指定せずに算術シフトの結果なんて意味があるの? 左シフト: value *= 2; 右シフト: value /= 2; で、何が不都合ですか?
Programming Language C++は10進コンピュータでも動くように設計されている。 データの内部表現に規定がないのはそのため。
>>505 2 の n 乗での乗除算のポータブルで高速なコードを聞きたかったんじゃないの?
boostが使えない環境でスマートポインタをこしらえる意義はあるだろうか?
boostも他のライブラリも使えないなら普通に書くだろうな
std::vector<bool>は黒歴史
でも0xでも生き残ってんだよなぁ
512 :
510 :2010/04/04(日) 12:25:01
>>511 一度標準になればクソ仕様だろうが生き残り続け
新人・周りが合わせていく。
それが魔のC++クオリティ。
ただしまともに使用されていないexport, 例外指定は別らしく
削除されたがな。
悪しき習慣だよな 互換性なんて放り投げればいいのに
514 :
512 :2010/04/04(日) 12:42:07
>>513 > 互換性なんて放り投げればいいのに
それなんてD言語
まあ悪しき習慣と言えばそうだけど、その腰の重さが
C++が繁栄した理由だと思うんだけど。
C言語とそれなりに互換性があり、過去のC++ともそれなりに互換性があってこその
C++じゃないか。さもなきゃ滅んで当然の言語。
>>515 存在すら忘れられてたな。autoは進化したというのに、、、
registerは次次期標準で動的クラスロードのために使われます
518 :
512 :2010/04/04(日) 13:50:48
>>516 > autoは進化したというのに、、、
もう別人になったと言う方が良いかもねw
newしたオブジェクトのポインタをコンストラクタで受け取り デストラクタでデリートするようなスマートポインタで、 それだけに機能を特化させた最軽スマートポインタクラステンプレートって ありますでしょうか。 正確には template<typename T> class MySmartPtr{〜}; みたいな形で、MySmartPtr<Base>とMySmartPtr<Derived>には特に互換性など必要なく、 動的削除子などの工夫や所有権の移動などもちろん備わっていなくていいです。 ただしoperator -> と operator * と std::swap の特殊化ぐらいは必要で、 例外安全かつ例外中立なものです。 よろしくお願い申し上げます。
auto_ptr
>>520-521 auto_ptrは所有権の移動処理を行なう部分で
無駄なバイナリができるんじゃね?
自作するのが早いかな。
テンプレート関数だから実際に所有権移動しない限り(=コピコンやoperator=を呼ばない限り) 無駄なバイナリはできない
524 :
520 :2010/04/04(日) 23:39:19
>>521-523 ありがとうございます。
std::auto_ptrは
C++0x - Wikipedia, the free encyclopedia
ttp://en.wikipedia.org/wiki/C%2B%2B0x unique_ptr will be provided as a replacement for auto_ptr which will be deprecated.
とのことで何れは削除されるか少なくともコンパイル時にwarningが出そうで
なんか気にくわないんです。
が、ひとまず今年ぐらいはstd::auto_ptrで行こうと思います。
ありがとうございました。
std::unique_ptrが使える環境ならそっちの方がいいね
unique_ptrってもう対応してるの?
int foo(int, int); な関数があったとして foo(foo(foo(foo(0, 1), 2), 3), 4); と書くのはステートメントの両端に文字を付け足さなくてはいけなくて`気持ちが悪いので infix infix_foo = foo; 0 infix_foo 1infix_foo 2 infix_foo 3 infix_foo 4 ... 的な事をしたいんですが、boostとか超大手ライブラリにそういった機能をするものはありませんか?
GCC4.4以降やVS2010なら
boost::operatorsで演算子を定義してしまうか、 この処理だけでいいならSTLのstd::accumulateを使うか
>>527 やめろそんなこと
どうしてもやりたけりゃこうだな
ひどいコードだ
struct foo_helper{
int tmp;
foo_helper(int i) : tmp(i){}
operator int(){return tmp;}
foo_helper operator->*(int i){
return foo_helper(foo(tmp,i));
}
};
foo_helper(0) ->* 1 ->* 2 ->* 3 ->* 4 ...
素直にループ回せばいいじゃん
とういうか可変引数でよくね?
というか再帰を使うべきじゃね?
>>533 > というか再帰を使うべきじゃね?
決定打だな。
0 ... 4っていうのは飽くまでも例に過ぎなくて 列を何らかのコードで出力せずに手入力の必要があるからinfixが必要だって言ってるんだよ。 再帰とかループとか的外れな事を言い出す奴は何考えてるの? 可変引数は型検査できないから論外。
入力をイテレーターのパターンに当てはめて実装する。
conceptは死んだのだよ。
入力ったってコーディングだろ? 労力割いてもいいこだわりなのか?的外れなこだわりなのか? 徹夜明けの現実逃避か?ん?
やめろ・・・
>>535 手入力が必要だったらループや再帰が的外れになるの?
意味わかんない。
541 :
デフォルトの名無しさん :2010/04/05(月) 10:30:43
inject ? accumulate ?
ここまでの情報では accumulate 一択だな。
>>543 どの仕事だよ?君には535の職業が分かるのか?
無職かもしれないだろ
>>544 > 無職かもしれないだろ
クソフイタwwww
普通にboost::assign使うかもしくは operator()をオーバーロードして なんとかしちゃダメなのか
535は結局どうしたいんだ
>>529-530 で答えは出てるのに何故それを無視してわざわざ噛みつくのか
荒らしたいだけなのか
理解できなかったんじゃね?w
>>547 >>527 ではないのですが
boost::assignとoperator()のオーバーロードだと
どんな感じの実装になるんでしょうか
スマートポインタってみんな再発明したがるけど たいていの場合shared_ptrあたりのほうが優秀なんだよな shared_ptrは遅い遅い言われるけど致命的に遅いわけじゃないし shared_ptrがボトルネックになるなら生ポインタ操作するだろうし・・・ でも、再発明したがるんだよなぁ・・・
リロードしてなかった流れぶった切りすまそ
結構勉強になるし、動的削除子ありで非共有のスマポはboostに無いから作る価値は有る
>>551 そもそもboost::shared_ptrは
・多くの環境をサポート
・マルチスレッドも安全
・ちゃんとよくレビューされていて自作よりずっとずっと安心
という利点があるしねぇ。
scoped_ptr と shared_ptr があれば大抵事足りる
>>553 非共有ってことはauto_ptrみたいに破壊的コピーを行うもの?
それとも深いコピーを行うスマートポインタ?
個人的にはboost::anyの方が魅力的だけどな。 shared_ptrの機能とかマルチメソッドとかと共存できるし。
>>557 boost::anyって使い道が分からない。
実装は目から鱗が落ちるようだった。
待っていれば誰かがboostに作ってくれる説に一票
>559 マルチメソッドがないと価値半減だからなぁ。 マルチメソッドがあるとanyに保存したデータの詳細を意識せずに操作することができるようになるんだけど…… 前にboost/vaultに突っ込んだけど誰も興味無いみたいだから放置。
anyはパフォーマンスで不利だし、anyを乱用する設計が良い設計とは思えない
そりゃそうだろ。実行時に解釈するかコンパイル時に処理するかで変わるわな。 用途を考えずに乱用する設計が良くないのはanyに限った話じゃないだろうね。 性能問題があるとしても(将来的な)拡張性という面でany&マルチメソッドは魅力的だけど。
昔のVBにはVariantという型があってな
そもそもマルチメソッドにany必須じゃねーでしょ c++ならコンパイル時にできるだけ決定するのが基本だし 実行時に型判断を回すとしてもわざわざ一回anyに入れてコストふやす必要はない
今も昔もC#にはObjectという型があってな
C#とか最近の言語出されても
C言語にはvoid*という型があってな
JavaにもObjectという(ry
>565 だから逆だって。anyの中身に応じて(自動的に)メソッドをディスパッチしてくれる機能が欲しい。 別にマルチメソッドするためにanyを活用したいわけじゃない。 もともとany使いたい時はソースコードと型情報を切り離して使用したいケースが多いんだけど、 現状のanyだと実際に使用するとき中身の型をソースコードに書かなきゃいけないから不便なんだよね。 リフレクションとかある言語だとそれを活用すればいいけど、C++にはそんなの無いからね。
逆ってなんだよ。現実的に考えてコストが増えるだけの非効率なものだからあんまり必要ないって言ってるんだよw
Boost.VariantにVisitorの組み合わせはちょっと違う?
>571 判ってないなあ。コストかけてでも動的な柔軟性が欲しいこともあるって言ってんだけど。 最初の設計段階ではかなり重宝するよ。 性能が欲けりゃ仕様が固まってパフォーマンスチューニングする段階になってから修正すればいいんじゃね?
>573 そんな感じ。 ただboost::variantだと代入できる型が決め打ちになるけど、boost::anyだと何でも突っ込めるという違いがある。 まあ、何でも突っ込みたくなるような事態になるのは少ないとは思うけどね。
anyの使い道か mapの値をanyにしてしまうとか 事前にanyに格納する型を数パターンに決めておいて キーに対応する型を知っている場合は直接指定して 知らない場合は事前に決めた数パターンの型でチェックして値を取り出す これでmapの値の型が多少柔軟になるんじゃないかな クリティカルな処理には向かないだろうけど バックグラウンドとかでやりようはあるんじゃない? まあ使った事ないんだけどね
boost::anyの実装って動的削除子と同じように仮想関数テーブルを使う仕組みで良いんだよね コード自体はシンプルだがC++について知り尽くしてないとこんな発想出てこないわ どういう頭の中身してるんだろ
win linuxで使える拡張子判定ライブラリはありますか
magicは?要求レベルを満たしてるかどうかは分からん。
class A { typedef int type; }; template<typename T> class B : public A { typename T::type a; type b; // OK }; template<typename T> class C : public T { typename T::type a; type b; // NG }; class Cで、NGとなってしまう理由がわかりません。 どなたか解説願えませんでしょうか
>>580 そのtypeがコンパイルできないのは当たり前なんだが
逆に質問するがそのtypeはどの型だと思うんだ?
>>581 ここはスレ違い
Linux板にGTKスレがあったはず
on Windowsならム板にもあるが
そんな曖昧な質問しにいっても荒れるだけだから
せめてテンプレサイトとか使って環境構築とサンプルのコンパイルや
読み下しをしてわからない所を具体化すべき
>>580 name lookup のルールが違うから。
template 引数に依存しない名前(non dependent name)は
定義時に名前解決されこの場合 template な基本クラスまで見に行かない。
dependent name はインスタンス化された時点でも
lookup されるので template 基本クラスまで探索される。
two phase lookup でぐぐれば良いと思うよ。
>>59 > static_cast<void>とか最近まで知らなくて、わざわざvoid用に特殊化してたよ。
すごい遅レスだけど、
これってどういう意味?
static_cast<void>なんて人生でいまだ使った事がないんだけど。。。
template<class T> typename T::result_type call_foo(T const& t) { return static_cast<typename T::result_type>(t.foo()); }
途中で送信してしまった。 ↑で T::result_type==void のとき、 return static_cast<void>(...); は return; と同じ意味になる。 たぶんそういう使い方のことじゃないの。
一応実行はしてくれるから同じにはならないぜ ちなみに VC++ 6.0 ではまだこの仕様に対応してなかったはず
この仕様ってのは、void 式を return できるという仕様ね。 void 式自体は普通に使える。
6.0って現役なのかw
VC6のことは忘れろ
結構最近まで現役だったわ 流石に退役したけど
593 :
585 :2010/04/06(火) 22:47:05
ほっほー。 なるほどなるほど。 ありがとう。 いやはやまたもやバッドノウハウが増えた。
バッドじゃねー
VC6とBCB5はマジで世界中で窓から投げ捨てることを義務化する法律を作るべき IE6と同類だわw
>>595 > IE6と同類だわw
IE6より達が悪いww
そうだな、 「奥が深い」と申し上げるべきであった。 失礼した。
>>597 void のときは特殊化すべしという
パッドノウハウが改善されたわけだ。
わかんない事を何でも否定すんなよ。
パッドノウハウ…
voidへのキャスト自体はCの頃からあった 関数呼び出しに付けて戻り値を無視する事を明示したり
>>601 struct A
{
typedef void result_type;
int foo() const { return 0; }
};
探索木と探索木じゃない木の違いって何なんですか?
木 ⊃ 探索木 だろう。木が一般的で探索木が特殊。
>>607 探索に都合がいいように作られてるって事でしょ。
二分探索木なら大小関係に制約を置くとか。
探索木じゃない木の例に 構文解析の結果、木構造になる 構文解析木とか。
>>603 ノードって読み替えたらいいとか=ただの木
>>608 ,609,612
ありがとうございます。
順序付けされた木構造をいうのですね
thx 特殊化ってオブジェクト作るときにされると思ってたんだけど違うのか…
コンパイルするときに、そのコードで必要な部分のみされる、じゃないか?
>>616 コンパイラは上から読んでいく1パス野郎だから、その下に書いてある内容なんて
完全シカトされる。
節子、それ探索木やない、順序木や
template <int a, int b> struct x {}; template <int a> struct x<a, a> {}; // ok template <int a> struct x<a, a + 1> {}; // ng なんで最後のダメなの?
テンプレートパラメータ(a)に依存したテンプレートアーギュメント(a+1)は許されないのでしょ。
>>621 それなら a 単体は依存しないのかって話になっちゃうよ。
>>620 エラーメッセージは何て言ってるの?
>>620 gcc でコンパイルしたら↓のエラー。
> :5: error: template argument '(a + 1)' involves template parameter(s)
template まわりの規格文面を "involve" で検索したら、関連箇所が見つかった。
14.5.5 Class template partial specializations p8
> Within the argument list of a class template partial specialization,
> the following restrictions apply:
> - A partially specialized non-type argument expression shall not
> involve a template parameter of the partial specialization except
> when the argument expression is a simple identifier.
単純な識別子(この場合 a )として使うのはいいけど、それ以外の式はダメと定められている。
任意の式を許すとしてしまうと、特殊化のパターンマッチが終わらない可能性が出てくるとか、
そういう話かと。
なるほどーthx template関連はいくら勉強しても先が見えないですね…
x<a, b>内で差b - aをspecializeしてdispatchしろ
std::string(str_ptr).size() std::strlen(str_ptr);
>>626 俺の感覚では全部NGなんだが、何で動いてるんだろう??
static_cast<std::string&&>(str_ptr).size(); 右辺値参照でこうしたいんだろうけど無意味じゃないか
つーか無意味なキャストはやめよう
>>626 どちらも std::string の一時オブジェクトをひとつ作るだけ。動作は変わらない。
どちらかと言えば 1 のほうが意図を直接的に表している分、望ましい。
ただし、そのコードそのままのことがほんとうにやりたいことであれば >627
using namespace std; してないソースが読みづらいんですけど どうしたらいいですか?
strlenじゃだめなの?
usingは良くないっていうけど boost::mpl::placeholders::_1とか書いてたら死なない?
>>635 死なないけどめんどいんで、できるだけスコープを絞って using する。
且つ、できるだけ using namespace ... は避ける。
識別子のはじめに _ が付くのは処理系で予約されてるから、プレースホルダーで_1とか見るたびに本当に気持ち悪くて鳥肌が立つ。 しかも_0からじゃなくて_1だからな。吐き気がする。
予約されているのは、先頭アンダースコアに続く大文字アルファベットと、 場所によらず2連続のアンダースコアだけじゃなかった?
あとグローバルネームスペースでの先頭アンダースコアに続く英小文字ね。 これについても _1 は該当しない。
>>639 これで 637 の鳥肌と吐き気も治るなww
俺の下痢は・・・?
template引数が複数あるクラスの一部の関数のみ特殊化したい場合って結局のところタグ使うのが無難なのかな
>>639 え
俺、まだC++始めたてだった頃にアンダースコア先頭に入れた数値をメンバで持ってたら
今標準化委員会にいる人に「処理系で予約されてるよ」って言われたんだが...
合法違法どっちにしろ_1はキモイと思う。終わり
>>649 嫌なことから逃げてるだけじゃ活路は開けねー
俺は使わせてもらうぜぇーーーーー!!
キモいってなんだよ。ただの文字だろ。馬鹿じゃないの?
美意識は分かるが幾らなんでもたかがプレースホルダーに対して過剰反応しすぎ。
B式
void *p = new std::string(); delete p; これってサイズ分からないはずですけど、 どんな処理がされるんでしょうか?
配列でないオブジェクトは前後のリンクからサイズを算出する事が可能 であり、実際にそのようにしてdeleteを行っている
さぁ?
>>656 sizeof(std::string)の大きさのメモリを確保する。
std::stringのコンストラクタを呼び出す。
std::stringのデストラクタを呼び出す。
メモリを解放する。
サイズはsizeof(std::string)です。わかります。
ちょっと書き方を変えて void del_func( void *p ); void func() { del_func( new std::string( "delete me!" ) ); } void del_func( void *p ) { delete p; } ふむふむ、delete自体はサイズが分かってるんですね。 デストラクタも呼ばれるとは意外でした。 だったらvirtualなしのデストラクタも呼び出してほしいなぁ
>>661 あ、ごめん。void*に気づかなかった。
デストラクタは呼ばれないだろうね。
delete void*でデストラクタ呼ばれんのって規格で保証されてんの?
new した時の型かその基底クラスの型以外の型で delete した時の動作は鼻から悪魔
基底クラスの場合でも virtual デストラクタが無いとダメなんだからね。
横からすいませんが、 >基底クラスの場合でも virtual デストラクタが無いとダメなんだからね。 これの理由ってvirtualでない場合、なんと言うか、継承と無関係なその層固有の物みたいに見られるから スルーされちゃうのかな。 どうしてそうなのか理由よくわかってない俺。詳しい人教えて
>>666 ポインタの型からデストラクタを呼ぶので、派生クラスを指しているとは
夢にも思ってないので呼ばないわけ
virtualを付けると動的に結合されるのでその都度呼ばせる事ができる
その代わり効率が少し低下する
>>666 この条件で未定義動作になると規格で定められている。
667 が言ってるのはきっと何か特定の実装での実験結果なので、あまり真に受けないで
おいたほうがいい。
669 :
666 :2010/04/10(土) 00:41:53
>>667 なるほど!わかりやすい説明ありがとうございました!
なんかすっきりしたww
670 :
デフォルトの名無しさん :2010/04/10(土) 00:43:33
deleteを独自に定義とかしていない限り、 struct Derived : Base {}; Base * p = new Derived; delete p; としたとき、BaseがvirtualなDestructorを持っていない場合の 動作は、標準C++では未定義の動作である ///////////////////////////////////////// ということを知らないヤツが居て困るんだけど。 彼らは「Derivedクラスのデストラクタが呼ばれないだけでしょ? 特にDerivedクラスのデストラクタに仕事はさせてないから 問題ないよ」とほざいていたりする。
どうでもいいけどPOD型の場合 void *pgr = new int[2]; delete pgr; これはデストラクタとか継承関係がなく、ただメモリ開放すればいいだけに思えるけどだめなの?
そうなるとstd::vectorを継承した独自のコンテナクラスなんかとんでもない話だな virtualなデストラクタを持ってないから未定義の動作だ
確保と開放が対になってればPODはメモリ操作だけでいいよ
template<class T> struct wrapped : std::vector<T>{ virtual ~wrapped(){ this->~std::vector(); } }; そしてどっかでoperator =(T, std::vector<U>)を定義して中で例外をthrowさせる。 じゃだめなの?
>>674 多態動作をさせないのならそれでもいいかもしれんな
しかし危険だな
operator =(T, std::vector<U>*)の間違いか?
>>671 そう。未定義動作。
それとは別にそのコードだと配列なので delete [] pgr じゃないといけない。
このため char *pgr だったとしても未定義動作。
最新のドラフトだと "The operand shall have a pointer to object type, ..." となっているので、
void はオブジェクトでは無いことと合わせてコンパイルエラーになってくれるのかもしれない。
>>674 そのクラスがstd::vector*から指していたらdeleteした場合鼻から悪魔だよ
つまりあまり役に立たない
new type;とnew type[num];で動的削除子の割り当てを変えたいから 前者ならobject_ptr<type>、後者ならarray_ptr<type>のそれぞれtype*にキャストできる型を返して欲しいとは思ったり思わなかったり
wrapped*へのdeleteだとstd::vectorのdestructorがvirtualじゃなくても wrappedからstd::vectorのdesutorakuta-動かせばいいのは分かるから template<class T> struct wrapped : std::vector<T>{ virtual ~wrapped(){} }; もだめなの?って横から思った。
>>681 だからwrapped*から操作する分には問題ないと思う
問題はvector*からdeleteすると鼻から悪魔だよって事
だったらグローバルにoperator=を作って中でassertとかすりゃいいじゃん
private継承だからvector*からdeleteされる心配はない だが~wrappedの中で~vectorしてるとデストラクタが2回呼ばれるから必ずバグる
代入演算子ってメンバー関数として以外に定義可能だったっけ?
private継承だったか それなら普通に包含使ったほうがいいな
>>685 boost.assign に += とか -= とかメンバでないやり方でオーバーロードしてるのがあるけど = がどうかは知らない
operator=だけは特別扱いで、メンバ関数としてしか定義できないことになってる operator+=とかは+や&&や->*とかと同じただの二項演算子だから外でもOK
あqsうぇdrftgyふじこlp;
ある関数内で宣言されたstatic変数のアドレスをマップに格納しておき、 それを別の関数からマップを介して取得する、といったことは可能なのでしょうか?
可能 単にmapを経由するだけの話
BaseクラスとDerivedクラスがあった時に、 Base* b = new Base Derived* d = new Derived; *(Base*)d = b; こういう風にBaseクラスの部分だけコピーして上書きしてしまって良いのでしょうか? とりあえず動いてるみたいですが……
Derivedの先頭アドレスにBaseが配置されているとは限らないからまずいんじゃない? DerivedがAnotherBaseとBaseを多重継承してればアウトだと思うし、 そうでなくても保障されていないのでは?
>>692 そのコードそもそもおかしくない?
Base* b = new Base // bはポインタ
Derived* d = new Derived; // dはポインタ
で
*(Base*)d = b; // 左辺はインスタンス、右辺はポインタ
だぞ?
とりあえずも何も全く動かないと思うが、本当はどういうコードを想定していたの?
それがダメだと void func(Hoge *p) { Hoge tmp(*p); ・・・; }; とか書いたら折角ポリモーフィックにしたのにサブクラスで使えなくなるってことか そんなバカな…
696 :
670 :2010/04/10(土) 12:21:21
>>672 > そうなるとstd::vectorを継承した独自のコンテナクラスなんかとんでもない話だな
> virtualなデストラクタを持ってないから未定義の動作だ
こういうヤツが居て困ると俺は言ってるんだ!
なんでそういう風に断言するのかね君は。
//////////////////////////////////////////////////
struct MyContainer : std::vector<int>
{};
でも
std::vector<int> * p = new MyContainer;
で未定義の動作になるのは
delete p;
とした時だけで、例えば
delete (MyContainer*)p;
だったら未定義の動作にはならない。
あるいは
boost::shared_ptr< std::vector<int> > * p(new MyContainer);
としても未定義の動作にはならない。
そもそもMyContainerを基底クラスのポインタに入れるということをしなければ
全然問題ないし。
「ポリモーフィックにしたのにサブクラスで使えなくなる」???
>>695 落ち着いて自身のレスを読み返し、
何についてのレスなのかもちゃんと書け。
struct A {}; struct B : A {}; A a; B b; A* p = &b; *p = a; これが許されるのかどうか自分も知りたい
>>699 はぁぁあああ??? 自分「も」?
誰がそんな話題を振った? そんな何の問題も無い通常の代入を?
>>672 protected継承しようぜってじっちゃが言ってた
ミスりました。本当は BaseクラスとDerivedクラスがあった時に、 Base* b = new Base; Derived* d = new Derived; *(Base*)d = *b; こういう風にBaseクラスの部分だけコピーして上書きしてしまって良いのでしょうか?
>>703 一つの処理系の実行結果だけを見て「大丈夫」と言われても・・・・
規格から該当部分を探してこいよ
>>705 逆ギレみっともない
IOS/IEC 14882:2003から探してこいって言ってるんだ
×IOS ○ISOな 言わなくても分かると思うけど 突っ込む奴は馬鹿
春休みってまだ終わってねーのか?
今日は土曜日だろ?
真面目に単位稼ごうとしたら土曜でも講義とるだろ普通
自己言及乙
社会人ですが何か?
713 :
670 :2010/04/10(土) 13:48:01
>>702 > こういう風にBaseクラスの部分だけコピーして上書きしてしまって良いのでしょうか?
そういう変な考え方をすると分からなくなるかもしれないけど、
普通に考えて
*( (Base*)d ) = *b;
は
*( (Base*)d )というBase&型の左辺値に対して
Base::operator = (*b);
を呼んでいるだけだろ?
ということは
規格の上では未定義の動作にはならない。
ただそれで問題ない動作をするかどうかは
Derived x;
x.Base::operator = (*b);
で大丈夫な実装になっているかどうかに依存する。
///////////////////////////////////////////////////////
>>703-712 お前ら誰か一人でも実りのあるレスができるヤツは居ないのか。
規格を嫁とかどんな質問もそれで片付いちゃうわけだが、
はっきり言ってバカでも言える事だし実りがあるとはちょっと言い難い。
>>713 ありがとうございます。
Baseクラスの代入演算子が正しく動作すれば問題ないのですね。
仕様書読めとか入っている馬鹿は死んで欲しい。
スーパークラスにサブクラスを代入しようとするとコンパイラがオフセット計算してくれるみたいね
716 :
デフォルトの名無しさん :2010/04/10(土) 15:43:20
どう書けば馬鹿のままポーズ保てるか必死に考えた結果がコレなんでしょ。
質問する側の態度じゃないよね 社会人とはとても思えない
朝鮮人なんじゃね?
このスレ日本人なんていたのか
時々あきらかに中国人っぽい書きこみはあるな
そんなこと無いあるよ
天安門事件 よしこれでチャンコロは消えた。
六四天安門/天安門大虐殺じゃないの?
Free Tibet でもよい
エロ関係多いなwww
便乗してちょっと質問です。 class CBase { public: int m_base; }; class CDerived : public CBase { public: int m_derived; virtual void v_func() {} }; // グローバルデータ CBase g_data00; CDerived g_data01; // グローバルデータへのポインタを取得する void getDataPointer(CBase** pp_data, int type) { switch (type) { case 0: *pp_data = &g_data00; break; case 1: *pp_data = &g_data01; break; } } (続く)
731 :
730 :2010/04/11(日) 00:35:27
int func() { g_data01.m_base = 10; g_data01.m_derived = 20; // グローバルデータを受け取る CDerived* p_data = NULL; getDataPointer((CBase **)&p_data, 1); return 0; } 引数によって色々なデータへのポインタを受け取る関数を作ったつもりが、 継承先に仮想関数があった場合に上手く行きませんでした。 期待した動作 → p_data->m_base == 10、p_data->m_derived == 20 実際の動作 → p_data->v_func == 10、p_data->m_base == 20, p_data->m_derived == 不定 p_data = getDataPointer(1); と改造した場合は上手く調整してくれたのに…。 アップキャストは安全だ!と思ってたのに、キツネにつままれたようでした。 CDerived* → CBase* は安全でも、CDerived** → CBase** は安全じゃないんでしょうか。 実際は複数のデータを受け取ることもあるので、戻り値で受け取る方法は使えません。 何かいい方法はないでしょうか。
>>731 > CDerived* → CBase* は安全でも、CDerived** → CBase** は安全じゃないんでしょうか。
そうだよ。前者は暗黙変換が許されている。後者は reinterpret_cast が必要になり、
変換によって得られた値は安全に使用できない。
正直、Cスタイルキャストを持ち出しといて「安全じゃないんでしょうか」なんて聞いたら
「あたりまえだ間抜け」などと言われても仕方がないと思う。
前者の逆変換が static_cast (あるいは dynamic_cast )で可能なので、以下のように書けばいい。
CBase* p_base;
getDataPointer(&p_base, 1);
CDerived* p_data = static_cast<CDefived*>(p_base);
733 :
730 :2010/04/11(日) 01:15:45
なるほど… C++ 風のキャストはタイプ量が多くて嫌っていたのですが、 使わないどころか使いこなせなくなっていたようです。反省です。 しかも static_cast でアップキャストが可能なのは初耳でした。 ありがとうございます! ここから先は興味本位の質問なのですが、 元のソースから getDataPointer の引数を void** にすると、期待通り動きました。 同じく static_cast では変換できない型なのですが、たまたまでしょうか? それとも仕様として認められているのでしょうか? void** を受け取る関数は API などにも多くあり、 それらが動作不定とはあまり考えたくないので気になります。
734 :
730 :2010/04/11(日) 01:16:34
訂正。 ×しかも static_cast でアップキャストが可能なのは初耳でした。 ○しかも static_cast でダウンキャストが可能なのは初耳でした。
>>733 reinterpret_cast による変換結果は実装依存(コンパイラの自由だけど定められた動作)に
なるので、そのような変換が期待したとおりに動くような実装になっているかもしれない。
コンパイラなどのドキュメントに対応する記述を見つけられないのであれば、たまたまだと
思っといたほうがいい。この場合だと reinterpret_cast は必要ないわけだし。
実験してみたけど、static_castでダウンキャストが出来るのは、 dynamic_castが必ず成功する事がわかっている時に限られるみたいね そうでないとdynamic_castは0ポインタもしくは例外を投げてくれますから
struct EMPTY { }; struct X { float x; }; template <unsigned int N> struct hoge { union { float f[4]; struct : public loki::select<N >= 1, EMPTY, X> { }; }; }; 上のようなコードで hoge.xとhoge.f[0]を等価にしようとしたのですが、出来ませんでした。 struct : public loki::select<N >= 1, EMPTY, X> { } a; とするとhoge.a.xとしてアクセス出来るのですが、無名共用体の中に無名構造体を使い 外側からアクセスできる裸のメンバを作る場合、継承を使ってメンバを増やすことは 出来ないということでしょうか? 何か方法ありましたらお教えください。 環境はVC2008Expressです。
738 :
737 :2010/04/11(日) 02:26:01
すみませんちょっとおかしかったので訂正します&あげ忘れたのでage struct HOGE { (略) } hoge; です。
739 :
737 :2010/04/11(日) 02:30:58
すみません、まだ間違えてましたorz template <unsigned int N> struct HOGE { union { float f[4]; struct : public loki::select<N >= 1, EMPTY, X>::result { }; }; } hoge; ですorz Nが0なら空、1ならxが入るようにしたかったのですが、1でもxがありませんでした。
>>737-739 それ、テンプレート関係あるのか?
無名構造体も VC++ の拡張じゃない?エラーメッセージは何て言ってるの?
741 :
737 :2010/04/11(日) 03:21:18
あ、そうですね、確かにテンプレート関係なかったです・・・ 普通にXを継承しても同じでした。 エラーメッセージは出なくてコンパイルは通りますが hoge.x = 1.0f; とかやると error C2039: 'x' : 'HOGE<N>' のメンバではありません と出ます
個人的つーか常識的にするべきじゃないだろう
744 :
741 :2010/04/11(日) 04:17:16
>>742 ありがとうございます。なんか変な結果になっちゃってますね・・・
用途を説明してなくてわかりづらかったですね、すみません。
SSEを使ったベクトルクラス(2〜4次元)を作りたかったんです。
128ビット境界でアラインして、__m128 v、float f[4]、float x,y,z,wで
同じ128ビット内の内容を指せるようにしたかったんです(リトルエンディアン限定)。
ともあれこの方法ではダメっぽいのでもうx,y,z,w全部入れてしまおうと思います。
ありがとうございました。
xmlを解析するライブラリはよくみかけるのですが、iniファイルを解析するライブラリってないのでしょうか? あと、ダブルクォーテーションとかエスケープシーケンスとか、解析の時の頻出な部分をやってくれるライブラリもあったらいいなと思います。
PHPのソースコード
boostのproperty_treeにini用の定義がある
zip内のファイルを部分的にreadできるライブラリありますか。 中身が10Gとかあると全展開するのに時間かかります。 部分的にロードできればHDDのスペースもいらないんですが。
また君か 環境依存OKと書かれてるスレで聞きなよ
前はtar.gzじゃなかったか
C#ってC++の進化言語って理解で正しいですよね
もうそれでいいよ
引数にメンバメソッドポインタ入れる方法を教えて template<typename T>result operator()(result(T::*t_f)() f){return f();} // 沢山の expected err …
>>752 別に就職先要らないならそれでおkだよ。
>>754 引数をres (T::*t_f)()にして
(p->*t_f)()で呼び出し
>>755 ドカタ業界に職求めるなんて絶対止めるべき
不幸な人生確定
STLスレなくなった?
質問です。現在 WindowsXPSP3, VisualC++2008Express で開発しています。 下記クラスを作成/利用したコードを、デバッグモードで実行すると、 free のタイミングで 「ヒープが壊れています」 と言う旨の例外が発生し、実行が停止してしまいます。 wcscpy_s の辺りに何か不安を感じるのですが、一体何がいけないのでしょうか。 よろしくお願いいたします。 class Test { private: TCHAR *strBuf; public: Test() { } ~Test() { if(strBuf) free(strBuf); // ← ここで「ヒープが壊れています」と出て中断してしまう } void setStr(const TCHAR *lpStr) { size_t len = (wcslen(lpStr)+1) * sizeof(TCHAR); if(strBuf) strBuf = (TCHAR*)realloc(strBuf, len); else strBuf = (TCHAR*)malloc(len); memset(strBuf, 0, len); wcscpy_s(strBuf, len, lpStr); } };
string wstringつかえ
wcscpy_sの第2引数はバイト数じゃない というかそのソースだとメモリ確保の時点で例外発生すると思うんだけど
763 :
760 :2010/04/12(月) 04:08:43
すみません、コピペした際に漏れた部分がありました。
Test() {
strBuf = NULL;
}
そして
>>762 さんにご指摘頂いた点、実は最初にインテリセンスで確認した所、
第2引数の部分が rsize_t _SizeInWords となっていたので、これは文字数だろうと思い、そのようにしていたのですが、
wcslen(lpStr) を渡すと死んでしまうという結果になっていて、それでバイト数にしていました。
・・・・が、今もう一度試しに wcslen(lpStr)+1 を渡してみた所、すんなり上手く行きました。ありがとうございました!
本当は
>>761 さんのおっしゃる wstring を使った方が楽チンなのはわかっていたのですが、
勉強の意味も込めまして、こんなコードを書いていました。 ありがとうございました!
764 :
760 :2010/04/12(月) 04:12:41
・・・って、あれ?なんで+1が必要なんだろう。 0終端とかそこら辺の理由かなと思ったけど、文字数指定してコピーする関数だから 例えば途中までの文字でも構わないだろうし、転送先も事前に 0 で埋めてあるのに何故なんだ・・・
765 :
760 :2010/04/12(月) 04:20:39
何度もすみません、やはり素直に wstring にします・・・ そうだ、Unicodeだと1文字のサイズが不定になるから 上の処理だと確保に失敗する可能性がある・・・orz
勉強ならnewとdelete使おう
あとコピーコンストラクタとか=()もどうにかしないとポインタのコピーとfreeが発生して怖いかも
>>764 文字数を指定してコピーする関数ではないからだろう
ドキュメント読んでみ
どなたか本当に
>>454 をお願いします。
>>480 >すぐあとに書いてあんだろうが
だそうですが、見あたりません。
すみません、演算子オーバロードについて質問です。 class Foo { public: int val[10]; Foo(const Foo &foo) { 〜コピー処理省略〜 } Fool operator = (const Foo &foo) { 〜valのコピー省略〜 return *this; } }; 例えばこのようなクラスがあった時、代入演算子のオーバロード関数の中で *this を返していますが、 これ、return のタイミングでコピーコンストラクタが実行され、コピー処理が二回行われるような気がするのですが、 このような場合、どのようにすればコピー処理を1度で済ませる事が出来るのでしょうか。
>>768 operator=は自分への参照を返さなければならないから、戻り値はFooではなくて"Foo&"。
参照はreturnでのコピー処理は発生しないから、コピー処理はoperator=の1回だけ。
>>769 レスありがとうございます。 実験してみた所、
class Foo {
private: int val[10];
public:
Foo(const Foo& f) {
〜コピー処理省略〜
}
Foo& operator = (const Foo& f) { // ※1
〜コピー処理省略〜
return *this;
}
};
void testtesttest() {
Foo a, b;
b = a; // ※2
}
>>768 の内容で実行すると operator = → コピーコンストラクタ の順で実行されていた物が、
※1の戻りを参照に変えた所、コピーコンストラクタ → operator = の順で実行されるようになりました。 これは、
※2の b = としてコピーコンストラクタが走り、※2の = a として operator = が走った??のでしょうか。
(ひょっとして、単にDeep Copy したいだけなら、代入演算子のオーバロードはいらない??のでしょうか)
もっともコード短くなるように書くのがいい。 デバッグしやすい。 間違えの総量が減る。 あとでパフォーマンス計り改良すればいい。 ホットスポット以外に手間掛けても意味なし。
>>770 >ひょっとして、単にDeep Copy したいだけなら、代入演算子のオーバロードはいらない
それでOK。コピーコンストラクターとoperator=は何も定義しないとメンバー同士をディープコピーをするだけ。
メンバーにポインターがある場合も同様。
コピーコンストラクターが必要な場合は、メンバーにポインターやハンドルの類があり、ポインター(アドレス)そのもの
のコピーではなくて、ポインターが指している中身をコピーしたい場合とか、ハンドルの参照数を管理したい場合とか。
>>772 Shallow CopyとDeep Copyの意味が逆になってない?
>>772-773 デフォルトのコピー動作が Shallow か Deep かどうかはクラス内のオブジェクトの
コピー動作がどちらになっているかによって決まるわけで、なんとも言えないはず。
>>770 本当にそれでコピーコンストラクタが動くか?
代入演算子の返値が参照じゃなかったときは返値の一時オブジェクトを生成するためにコピーコンストラクタが動くが。
>>770 のval[10]をコピーするのはDeepCopyとは言わないのでは
こういうふうに仮想関数を、戻り値を変えてオーバーライドするのは可能ですか? ベースクラスのポインターでduplicate()を呼び出すと、派生クラスのduplicate()を呼び出したい。 struct Base { virtual Base* duplicate () { return new Base; } }; struct Derived : public Base { virtual Derived* duplicate () { return new Derived; } };
>>778 それ自体は構わんと思うが、Effective C++の第31項に触れないか?
>>764 その操作を許してたらセキュアにならないからな
文字列終端は通常のstrcpy()の考え方
たしか_s系のDebugバージョンはコピー前にDestをFDで埋める
memset()乙
781 :
770 :2010/04/12(月) 14:23:04
>>775 すみません・・・ いまもう一度確認してみた所、
参照を返すようにした場合、コピーコンストラクタは動いていないようでした。
自分でも「なんで参照返してるのに、生成するような動きに??」とは思ったのですが、
良く見てみた所、どうもVisualStudioで、トレースポイントの挿入で打ち込んだ所がどうやってもズレてしまい、
上下に並んでいた2つの関数のうち、2つのトレースポイントが両方ともオペレータオーバロードの方を差していただけ、だったようです。
=ログに常に2行出ていた。
試しにメンバを配列やポインタでなく int の即値に変え、コピー処理のところで x += f.x のようにして増加状態を見て確認してみた所、
コピー処理にあたる行は1度しか実行されず、つまりコピーコンストラクタは実行されていない事を確認しました。
お騒がせしました。 皆様ありがとうございました。
>>779 31項「ファイル間のコンパイル依存性をなるべく小さくしよう」???
これ私の理解だとシグネチャーが違うので派生クラスのduplicate()が基底クラスのduplicate()を隠すはずなのですが、
何故か正しくオーバーライドできてしまっているので、最近のC++は仕様が変わったのかなと聞いてみました。
共変の戻り値でググレカス
Effective C++って言ったんだけど
>>783 うわこりゃひでえ
印刷して本にはさんでおくわ
788 :
778 :2010/04/12(月) 15:03:06
>>784 「共変」の「戻り値」でググると理解できました。
仮想関数のオーバーライドには共変の戻り値までは許されるのですね。すっきりしました。
何でお前はこんな重箱の隅の隅まで知ってるんだ……ありがとうございました。
789 :
デフォルトの名無しさん :2010/04/12(月) 21:42:02
>>783 ありがとうございます。
ご教示いただいた正誤表に
例外安全にすることができない。
->おそらく例外安全の強い保証が得られない。
があり、解決しました。
結局
>>480 >すぐあとに書いてあんだろうが
は知ったかぶりだったんですね。
まじめに考えなければ良かった。。。
後ろの4行は余計
いや知ったかぶりにはそう言わないと分かんないだろ まあこのスレには知ったかぶりが昔からいっぱいなんだけどな。
蛇足はバグを生む
> 1000回読んでから質問しろ" だとか今 読めば明らかにばかげた事を言っていたのに 正直にその後ろあたりをおよそ5回ほど熟読してしまったのですが、 結局 釣られていただけだと知りました。
共変戻り値のこと正直知らなかった。。。半年前に知っていたら。。。
>共変戻り値のこと正直知らなかった 職業C++メインプログラマじゃなかったら、そんなもん でも、職業C++メインプログラマなら恥ずかしい
799 :
デフォルトの名無しさん :2010/04/13(火) 07:13:51
2chでは無根拠の憶測すら断定口調で書き込んだ上、それに基づき相手を罵倒する。 よくあることです。 俺も2ch始めたころは…(ry
( ´ー`)y─┛~~ 実は俺も知らなかった…。C++め…どこまでも奥が深い。
>>789 mix-inって方法は知ってたけど、名前があるなんて知らなかった
俺もだ しかもWikipediaには「共変」という言葉の定義が数学的に しっかりされていて二回驚いた Cは一人の人間が作ったので割と思想は浅いが、C++は数多くの 各界の著名人が開発に関わっているので、そういう裏事情も知らないと 完全に使いこなすのはまず無理ってか C++ってプログラミング言語というガワを被された思想の塊だよな
用語は知らんかったが戻り値型の緩和についてはD&Eに書いてあったよ
えーどっちも有名な話だと思ってた
>>804 D&Eは途中で挫折したのでそこだけ読んでみた。
まさに上のduplicate(clone)みたいな仮想関数を実装するために拡張されたんだな。
確かにこれができないとキャストしまくりの汚いコードになる。
奥が深いぜC++
GetCellData( EXCEL::Range range ); ってどんな引数いれたらいいんだ? ::の意味がわかんねえ
大学の講義でBorland C++ Compilerを使うことになったのでプログラミングを始めてみた。 以前中高でHSPとAction Scriptはいじったことがあるけど、C言語系は初めてだ・・・。 というわけでブックオフで↓の2冊を買ってきたんだが、どうもネットで調べると明解C言語の方が評判良さげだね・・・。 林晴比古著『新訂 新C言語入門 スーパービギナー編』 同著『改訂 新C言語入門 ビギナー編』 あと、C言語について勉強するにあたって、色んな本が出版されすぎていて、 本の体系(ex. 大学受験の英語で言うところの「単語」「文法」「構文」「長文」「リスニング」のような分類)がイマイチ掴めない、ってのが困る。 どなたかC++やCの書籍の分類についてご教授頂けませんか?
テンプレがあるから推薦書スレいった方がいいぜ ここだと荒れそうだからよw
理解した
じゃあそちらのスレで質問することにするので
>>808 は無視して頂けると有難いです。
失礼しました。
>>808 > Borland C++ Compilerを使うことになった
バージョンにも依るだろうが、まさか5.5.1じゃねぇよな?
もしそうならそんな大学は即止めるべき。
関数のlookupでは、非テンプレート版>テンプレート版の順に探索される。 (テンプレート関数の呼出であると明示した場合はテンプレート版が呼ばれる) つまり非テンプレート版とテンプレート版が曖昧にならないから、 同名の関数を非テンプレート版とテンプレート版で定義しても問題ない。 もっと正確な仕様を知りたければ規格書読むべし。
816 :
811 :2010/04/13(火) 20:37:06
>>815 まずい所だらけだろ。
テンプレート周りを扱う時の絶望感が特にすさまじい。
テンプレートか・・なるほど。 constの特殊化とか出来なかった気がする。
右辺値を非const参照で受け取れてしまったり
イミフメイ
質問です。 下記のようにして、あるclassのインスタンスのポインタの配列を返す関数を書いています。 しかし上手く行きません。 どのようにしたら良いのでしょうか class Bar { 省略 }; unsigned int func(Bar*** out) { unsigned int cnt = 他所から動的に拾っているカウンタ; *out = new *Bar[cnt]; for(unsigned int i = 0; i < cnt; ++i) (*out)[i] = new Bar(); return cnt; }
821 :
820 :2010/04/13(火) 22:32:07
× *out = new *Bar[cnt]; ○ **out = new *Bar[cnt]; 転記ミスしました。すみません
某ブログでVisual Studio 2010 は Two Phase Lookupをサポートしていないとあるが、 具体的にそれだとどういった問題が起こるのでしょうか?
>>82 class Bar {
unsigned int i;
public:
Bar(unsigned int i = 0) : i(i) {}
void print() const {
std::cout << i << std::endl;
}
};
unsigned int func(Bar**& out)
{
unsigned int cnt = 10;
out = new Bar*[cnt];
for (unsigned int i = 0; i < cnt; ++i)
out[i] = new Bar(i);
return cnt;
}
int main()
{
Bar** bp;
func(bp);
for (int i = 0; i < 10; i++)
bp[i]->print();
}
vectorとshared_ptrを使って例外安全にしようぜ
いいやん 初心者に例外安全とか言うと絶対混乱するし Exceptional C++を読んでないとまず理解不能
この方がいいか int main() { Bar** bp; unsigned int j = func(bp); for (int i = 0; i < j; i++) bp[i]->print(); }
>>827 んなこたーないだろ。
エラーが起こっても漏れたり壊れたりしないようにするだけ。
これで混乱するようならプログラマとして問題があるんじゃないの?
>>829 「初心者に」って言ったんだけど日本語読めませんか?
>>830 エラーで漏れたり壊れたりするプログラム書いて誰がうれしいの?
初心者だからって何が変わるの?
っていうかむしろ vector や shared_ptr 使ったほうが簡単じゃね?初心者向きじゃね?
>>831 じゃつべこべ文句言わずにお前がプログラム書いてやれ
typedef boost::shared_ptr<Bar> BarPtr; typedef std::vector<BarPtr> BarPtrVector; unsigned int func(BarPtrVector& out) { unsigned int cnt = 10; BarPtrVector v; for(unsigned int i = 0; i < cnt; ++i) v.push_back(BarPtr(new Bar())); out.swap(v); return cnt; }
834 :
820 :2010/04/14(水) 02:03:23
>>833 あのー、全然理解出来ないんですが、勘弁してもらえませんか?
>>834 職業C++プログラマになるつもりがないなら勘弁してやる。
836 :
820 :2010/04/14(水) 02:09:18
はあ?あなた頭大丈夫?
なんでキレてるんすか?
838 :
820 :2010/04/14(水) 02:26:30
だいたい職業プログラマがこんな時間に起きてるわけないですよね?
>>822 他のコンパイラに持っていくと動かないコードがうっかりできあがってしまったりする。
>>838 ごめん職業プログラマだけど起きてる
このスレではROM専だった。
842 :
820 :2010/04/14(水) 07:36:36
>>834 >>836 >>838 は自分じゃありません
いま携帯で見てて電池切れそうなので取り急ぎ
>>824 ありがとうございます!今晩帰宅後に確認させて頂きます!
あと、shared_ptr と vector について、上で上がっている本は読んでいないですが、
意味と目的は理解してるので大丈夫です。
自分が理解できないものを初心者に理解されては困ると思ったバカが暴れていた、というわけだな。
例外安全とはどういう意味なんでしょうか?
Javaの移植しているんですが、アレコレ書いているうちに &や*、.、->が入り乱れたプログラムになって 自分でも統一しろよとか思えてくるんですが、そんなモンでしょうか・・? &(*iterator)->func().member みたいなのがいっぱい。 もう包含やめて全部ポインタにしてやろうかと思えるくらいに嫌な感じなんですが。
>>846 いっぱい出てきて嫌なららローカル変数なり関数なりにまとめればいいんじゃね?
そういうことをせずにぺたぺたコピペしてるから嫌な感じになってるんじゃないの?
>>811 >>829 みたいなのって100%指導者に向いてないタイプだな。
教えられる側の、特に初歩的な位置にいる人間の、理解力とか知識の蓄積をあまりに考えてなさ過ぎる。
今、Borlandのフリーコンパイラ+デバッガーで勉強してます。 今のところ、Borland C++ CompilerとTurbo Debuggerをダウンロードして、 パス設定やらilink32.cfgやらbcc32.cfgやらの環境設定を終え、フリーの統合開発環境をVectorで手に入れたところです。 ここで質問なんですが、Borland(今は違う会社ですが)でダウンロード出来るこれらのソフトだけでは、 開発環境としては「快適なエディタ」を欠いた状態ですよね?統合開発環境はあった方が良いんですよね? Vectorでフリーの統合開発環境を手に入れたので、それを使いながら勉強しようと思ってるのですが。
快適なエディタを欠いていることのみが問題なら、統合開発環境じゃなくて 快適なエディタを手に入れればいいだけじゃないのかな。 まぁいろんな開発環境を試すことも勉強になるからいろいろどうぞ
851 :
849 :2010/04/14(水) 13:10:48
ご回答ありがとうございます。 とりあえず色々なソフトを起動してみて、使いやすそうなBCC Developerに決めました。
bcc5.5は古い。最近の文法は通らない。新しいやつ入れろ。
30日試用版のコンパイラだけを使えばbcc5.5の上位最新板が使える
>>852 でもBorlandで配布されてる最新版フリーソフトって5.5.1ですよね。
新しい奴っていうのはシェアウェア(例えばVisual C++)ですか?
>>853 すみませんリロードしてませんでした。
30日間のトライアル版ですか・・・・。
確実に30日以上は勉強するつもりですし、トライアル版って基本的に嫌いなんですよ・・・。急かされている感があって。
とりあえずBCCで基本を学んでから、お金貯めてVC++やらVisual Studioやらを導入しようと思ってるんです。
bccの30日体験版か、gccか、vs2008かvs2010だな。 vc++は無料のやつある。vc++2010は最上位も今は無料。ベータ版とかだからな。
>>856 色々な情報提供ありがとうございます。助かります。
ところで、やっぱり開発環境って最初から一貫してたほうが良いんですかね?
でもあーだーこーだ言う前にとりあえずBCCで勉強しようかな、というノリなんですけども。
858 :
850 :2010/04/14(水) 13:31:44
トライアル版はideのライセンスが切れるだけ。 コンパイラ本体はライセンスで保護されていなくて自らやめなければ使える。 vc++2008expressか、vc++2010ベータは無料。
bccの利点はコンパイル速度が速いことだけ。 文法的、windowsのマッチ度的にも、vc++無料版に及ばない。 実戦・実務でも使えるのはvc++だろ。 コンパイル速度はよほどパソコンが遅くなければ大差はないと思う。
vc++もコンパイラだけのide無しの配布もある。 windowsSDKというのに入っている。これはコンパイラと必要ヘッダが入っているやつ。
862 :
初心者 :2010/04/14(水) 13:44:06
とりあえずレスが分かりにくいと思うので識別のために一時的に名前欄に入れておきます。
あと、分からない用語をググりながらなのでレスが遅くて申し訳ないです。
>>858-861 ありがとうございます。やっぱりVisual系の方が色々参考書籍・サイトも豊富ですしそちらにしようと思い始めました。
ちなみにパソコンは一昔前のXP標準搭載型で、CPUはintelのceleronです
詳しくは知らないですけど確かセレロンってショボいんですよね?w
864 :
初 :2010/04/14(水) 13:53:01
すみません。ググったところ、Windows SDKとVisual Studioって、開発環境って点では同じ意味に取れるんですが、何が違うのでしょうか? 何となく、SDKの方が扱う範囲が広そうな感じは受けますが、ちょっとよく分かりません・・・・。
>>861 > これはコンパイラと必要ヘッダが入っているやつ。
と既に書いてくれてあるだろう?
Visual StudioはIDE。開発環境だよ。
Windows Platform SDKはWindows ネイティブのアプリケーションを作成する場合に必要。 Platform SDKとBCCという組み合わせでもアプリ作っていける。
VS2008、VS2010 ⊃ WindowsSDKのはず。 基本的にはVisual C++を入れれば勝手に入る。 しかし最新版のコンパイラやヘッダはwindowsSDKにしか無い場合もある。 初心者はexpress SP1かvs2010評価版いれればそれだけで良いはず。
メモ帳とms-dos、 visual stduioでないide使うなら windows sdkだけ入れとけば出来る。
869 :
初 :2010/04/14(水) 14:14:54
>>865-868 なるほど。ありがとうございます。
とりあえず集合としては「SDK⊂VS」なんですね。分かりました。
SDKはコンパイラ・ヘッダファイルを含む一方、VSの方はコンパイラ・ヘッダ・エディタなどを統合的に含むので、こういう関係になるってことですかね。
とりあえずVS2008expressのVC++をインスコしようと思います。
>>868 やっぱり環境は統合されていた方が勉強・開発しやすそうなのでVSにしようと思います。ありがとうございます。
本当皆さん博識で勉強になります。ここは2chでも屈指の有意義な板ですね。
初心者ならg++とprogrammer's notepadで十二分
vs2008はのろいPCだと動作がつらい場合もある。 コード補完のインテリセンスというのを止めれば固まることは少なくなる。
872 :
初 :2010/04/14(水) 14:40:38
今VC++2008expressインスコしてます。 standard版との違いなんて正直、初心者には大差ありませんよね?
873 :
初 :2010/04/14(水) 14:48:34
調べましたが、express版にはMFC(Microsoft Foundation Class)とATL(Active Template Library)が無いんですね。 前者はWinAPIのバージョンの違いをイチイチ気にしないでプログラミング出来るようになるモノで、 後者はリスト構造のデータを手早く簡単に作れるようになるモノなんですね。
どっちも使わない。MFCは古典的で廃れ気味。ATLは使えるかも知れないが 解説している所少なめで、使いこなす人も少なめ。 ATL、MFCより難しいとされる直APIでも解説ページが多いことでこっちの方が楽という逆転もあり得る。
875 :
初 :2010/04/14(水) 14:54:29
なるほど。要は、express版ではプログラミングが快適になる機能が省かれているが、そもそもそれらの機能自体そんなに使わないのでexpress版で充分と。
え、なに、MSのライブラリを挙げるスレになったの?
APIをそのまま使っていくのもいばらの道だが、 MFCに甘んじるのは腐ったクソを食うようなもの。 OOPを他の環境で覚えてから、 自分でAPIをラップすれば多少はスカッとする。
GUIやるならC#やった方が断然楽。MFCとかマスターするのは時間の無駄。 C++/CLIでもC#と同様のことが出来るはずだが、情報少なめで急に難易度アップする。 c++とc#を臨機応変に使い分ける方が開発が短期間で済む。
expressに付いてるか確認できていないけど。 コードをトレースできるデバッガは大事。あとホットスポットの計測。 後者は体験版・有料だがインテルAmplifierというのがいい。 デバッガは、マイクロソフトの開発者が使っているというやつは 無料だが使いこなすのが難しい。
882 :
881 :2010/04/14(水) 15:25:59
if(・・・){ //ここに来たら停止 } こういうコードを挟み込めば出来るけど、その都度再コンパイルが痛いところ。
>>880 デバッガは初心者のうちからでも使えるかもしれないけど、
パフォーマンスについては地力がついてからでいいんじゃないかな
とはいいつつ、ある程度printデバッグでがんばるほうがいいようにも思ったりするけど、これはあくまでも主観。
マネージコードとアンマネージコードを組み合わせると一気にパフォーマンス落ちるから その意味でもC++/CLIは無いな。
じゃあ何故このスレに来た
だって、C++/CLIはこのスレじゃないでしょう
>>883 printfだと死んだ現場を確認出来ない。printfの前後のここでエラーだろうと推測して
それが間違えていることもある。一行ずつのトレースなら確実。
>>887 推測して間違えていることがあるというのを経験するのが、初心者にとって良いと思ってるんだ。
889 :
初 :2010/04/14(水) 15:35:48
専門用語多すぎ付いていけないワロタ とりあえずインスコが終わる気配ない上、そろそろバイトなのでまたいずれ疑問点があったら質問させて下さい。 ありがとうございました。
こんなコードを追加することで、メモリリークの調査できるぞ。 #include <windows.h> #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #define malloc(size) _malloc_dbg(size, _NORMAL_BLOCK, __FILE__, __LINE__ ) #define calloc(s1,s2) _calloc_dbg(s1, s2, _NORMAL_BLOCK, __FILE__, __LINE__ ) #define realloc(p,s) _realloc_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__) #define free(p) _free_dbg(p, _NORMAL_BLOCK) #define _recalloc(p, c, s) _recalloc_dbg(p, c, s, _NORMAL_BLOCK, __FILE__, __LINE__) #define _expand(p, s) _expand_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__) inline void* operator new(size_t nSize, LPCSTR lpszFileName, int nLine){ return _malloc_dbg(nSize, _NORMAL_BLOCK, lpszFileName, nLine); } #define DEBUG_NEW new(__FILE__, __LINE__) #define new DEBUG_NEW int main(){ _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); int *p=new int [100]; }
>>890 予約語を#defineするとか、
そんな悪い癖を付けさせるなよ。
>>890 そんなキモいマクロ大量に使う前に RAII を徹底しろ。
ファイル・ラインを使う以上マクロにせざるをえないんだよな
スマポとコンテナ使え
void f(MyClass x){} と void f(const MyClass x){} は標準C++では定義の重複と再宣言でコンパイルエラーになるのが正しいのでしょうか? また、 void f(MyClass x){} と void f(const MyClass& x){} ではどうでしょうか。 よろしくお願いします。
どうやって呼び分けんの?
booooooooooooooooooooooooooooooost::ref
>>897 前者は仮引き数がconstになっただけ。呼び出し元には影響しない。
後者は参照がconstになっている。
void f(MyClass x); // 引き数はコピーされる。関数内でも変更可。 void f(MyClass const x); // 引き数はコピーされる。関数内では変更不可。呼び出し元には関係ないので再定義となる。 void f(MyClass & x); // 引き数は参照される。関数内で変更可だが呼び出し元に影響する。 void f(MyClass & const x); // 元々参照の付け替えはできないのでこうは書けない。 void f(MyClass const & x); // 引き数はされる。関数内では変更不可。 void f(MyClass const & const x); // 元々参照の付け替えはできないのでこうは書けない。 void f(MyClass * x); // 引き数はポインタが渡される。ポイント先を変更できるし、ポイントする場所も変更できる。 void f(MyClass * const x); // ポイント先の変更はできるが、ポイントする場所は変更できない。ポイントする場所の変更は呼び出し元には関係ないので再定義となる。 void f(MyClass const * x); // 引き数はポインタが渡される。ポイントする場所は変更できるが、ポイント先の変更はできない。 void f(MyClass const * const x); // 引き数はポインタが渡される。ポイント先もポイントする場所も変更できない。ポイントする場所の変更は呼び出し元には関係ないので再定義となる。
903 :
899 :2010/04/15(木) 13:20:46
ああそうか。へんなレスしてすまんす
ゆるしてやるよw
deleteの関数ポインタってないの? void func(void (*d)(Widget *pw)) { (*d)(pw); } func(delete); こういうことしたいんだけどいちいち関数でラップしないといけないのかな
deleteは演算子だよ
>>905 boostのchecked_delete
908 :
897 :2010/04/15(木) 19:22:04
>>902 みなさんありがとうございます。
void f(MyClass x){}
void f(const MyClass& x){}
があったとして、
MyClass hoge;
f(hoge);
とするとどちらがよばれるのでしょうか。
規格ではオーバーロードの解決が曖昧になりますか?
曖昧になる
なぜ試さないのか 一回でも試してたらコンパイルできないとわかるだろうに…
>>889 話に乗り遅れたがQtという選択肢もある
3つバージョンがあるけどライセンスの相違だけで
開発環境の機能としてはどれも同等
公式
tp://qt.nokia.com/title-jp
【RAD統合環境】 Qt 総合スレ 7 【Win/Mac/Linux】
tp://pc12.2ch.net/test/read.cgi/tech/1270309416/
>>910 特定の環境でどうこうの問題じゃなくて、
規格の話を伺っています。
特定の環境でどうこうならとっくにそこでコンパイルしていますよそりゃ
>>912 すげー微妙な問題ならべつにしても
この程度の平凡な内容でもいちいち規格みないと先に進めないの?
つーかお前実は規格読んだ事ないんだろ?
読めりゃ質問しないで自分で見るもんな
規格も読めないのに規格にウルサイとか当た真ん中どうなってんのコイツ
>>914 5行も頑張って書いてくれたところ申し訳ないが、
すげー微妙な問題はお前に聞いても分からないだろ?
せいぜいこの程度がお似合いって事だ
>>915 妄想で周りの人間を格下と決めつけて優越感を感じたり、心理的ストレスから逃れようとするのは
集団生活で子どもがとる典型的な逃避行動らしいぞ
相手に噛み付く前に自分の事を見つめ直したらどうだ?
規格原理主義者を気取るならせめて規格に目を通すぐらいのことはしようや、な?
>>916 > 妄想で周りの人間を格下と決めつけて優越感を感じたり、心理的ストレスから逃れようとするのは
> 集団生活で子どもがとる典型的な逃避行動らしいぞ
> 相手に噛み付く前に自分の事を見つめ直したらどうだ?
まるで自分に言い聞かせているように読めるのは俺だけではあるまい
>>917 根拠のない断定と一緒にしないでいただきたい
無意味な煽りあいはやめようぜ
規格で決まってるとか適当に言っても信じそうだな
>>890 いつまでくそ古いVerのVC++使ってんだよ
>>918 だってお前のも根拠ないだろ?
どこに証拠があるの?え?
923 :
デフォルトの名無しさん :2010/04/15(木) 23:07:03
vector
924 :
デフォルトの名無しさん :2010/04/15(木) 23:10:01
std::vector<bool> って酷評されていますが、何が不便(デメリット)なのでしょうか。 また、使うことにどんなメリットがあるのでしょうか。 教えてください。 よろしくお願いします。
どこまで知ってるんだい?vector<bool>
boolの配列として使用不可能なのがデメリットと感じないのならビックリだ メリットは情報の圧縮
927 :
924 :2010/04/16(金) 00:06:35
vectorもboolもよく使いますが、vector<bool>は仕様が異様だから使わない方がいいと言われていたので、使った事がありません。 通常期待されるvectorの挙動と違うのですか。おっかないですね。
vector<bool>は規格で邪悪な特殊化が強要されてて 普通のvectorとは全く別物になってる
929 :
924 :2010/04/16(金) 00:16:02
ん?std::vector<bool>を使うくらいならstd::bitsetを使えばいいのかな……。。
930 :
デフォルトの名無しさん :2010/04/16(金) 00:16:52
それは気味が悪いですね。なんとも…。
Effective STL(だったかな?)でも vector<bool>は鬼子じゃあ、使ってはなんね って言ってたな
&[0] == &[1] うわあああ
>>921 最近まで6.0が現役とかいってた奴がいたからなw
crtdbg.h覗けばわかるけど
>>890 のマクロのほとんどは無駄だな
当たりつけてスタックトレースすりゃ大概見つけられるけど
newでファイルライン検出するのは相変わらずこの手法が一般的なのかね
>>929 なんのために使うのか明確にするのが最初じゃないか?
935 :
初 :2010/04/16(金) 11:57:29
昨日は大学だったので1日ぶりに来ました。 結局、C++じゃなくてまずはC言語から学ぶことにしました。 テキストは「基礎からのC」っていうのを使ってます。開発環境そろえるときにアドバイス下さった方々には本当に感謝しています。ありがとうございました。
>935 しかし、C言語のソートプログラムや文字列操作などは 実用的には勉強する意味がないぞ。 ポインタの学習などにはなるだろうが。 おすすめは、軽くC言語を知ったらSTLをやることだ。 効率性がC言語より格段に上がる。
C言語を学習するとき、その内容はCの文法と動作、およびテクニックとイディオムの 二種類(「基本」と「応用」)に大別できる。 実用的C言語を身に付けたい場合、学習時間の大半は後者に費やされるが、 最終的にC++を使えればよいなら、後者を学習する意義はほとんど無い。
無駄だとか何でそんなにがちがちに考えるのかね 学生なんだからいろいろ挑戦してみりゃいいじゃん せっかくCならCPUやハードウェアアーキテクチャを意識しながら組むのが望ましいかね
939 :
初 :2010/04/16(金) 15:10:21
とりあえず基礎からのC(見た感じ、
>>937 で言うところの「基本」が詰まってます)をマスターするまでは頑張ってみます。
あと、学生ですけど実は情報系の学生じゃないです。(経済系ですし、しかも公務員志望です。)
まあどちらにしても、何事もトライ&エラーが大事だと思うので、色々挑戦してみます。ありがとうございます。
template <class T, class U, class D = void> class X { X(void); X(const X &); X(const T &, const U &); // 以下いくつかのコンストラクタ }; template <class T, class U> class Y : public X<T, U> { inline Y(void) : X<T, U>() { } inline Y(const Y &y) : X<T, U>(y) { } inline Y(const T &t, const U &u) : X<T, U>(t, u) { } // 以下いくつかのコンストラクタ }; 実装用にダミーのテンプレ引数Dを持ったクラステンプレートXがあったとします XのインターフェースからDを隠蔽するために上記のようにXを継承してYをつくりたいのですが コンストラクタを移譲するだけのコードを書く手作業の手間とオーバーヘッドを無くすことは可能でしょうか?
そんなにコンストラクタが必要な理由がわからんけど とりあえずTとUのconstと&を取っ払って 中で実装に適合できるようにtraitsを定義してみては
おれだったらエクセル使うね。
C++0xっていつ出るんでしょうか? Boostでthreadやshared_ptr使いたいんですが、0xで標準になるっぽい事を考えるともうちょっと待った方が・・・と悩んでいます
待つことができるということは取り立てて必要ないんだろ 待ってりゃいいんじゃね?
0xのshared_ptrってboostのとどう違うの?
>>943 今年中に仕上げたいんですが、途中で0xが出たら無駄足になりそうで。
早めにやるに越したことはないものなんです
3ヶ月以内とかに出そうですかね?
そんなすぐに出ることは絶対にありえない
そうですか・・・ありがとうございます Boostでやろうと思います
>>946 > 今年中に仕上げたいんですが、途中で0xが出たら無駄足になりそうで。
ありえない。
C++0xはなんだかんだで最速で規格が実装されるのが2011年内ってことは確定的だから、
そっから各コンパイラベンダがC++0x実装するまでと考えると
・・・な。分かるだろ?
別に0xが出てからでもboostのスマポを使ってもなんの問題はない 次のプロジェクトからstd::shared_ptrを使えばいい
namespace std{ using namespace boost; } って規格違反しておけばいいんだよ
>>952 わざわざそれをしなくても
typedef なり マクロなりすればいいんじゃね?
俺はstdよりboostのがしばらくは信用できそう
(stdは枯れるまで待ちたい)
だからboostにするけど。
随分前の事だがtr1::shard_ptrがboost::bindに適合しないということがあったんで 他でもあったら面倒だから適合性が問題になりそうな場合はboost一択だな 少なくとも今の所は
955 :
デフォルトの名無しさん :2010/04/16(金) 20:26:05
ttp://codepad.org/t3DK48jC このようなコードがあります。
ここでnamespace NS_Aの中のものは他人が作ったコードで変更不可、namespace NS_Bの中のものは私が作ったコードで少しくらいは変更可能とします。
このコードにおいてはまあ何の問題もないわけですが、
もしもNS_A::fooが
ttp://codepad.org/xjXwEurR のようにコメントアウトされていた場合、
g++, Comeau C++ではコンパイルエラーになりますが、
VC2008でコンパイルエラーになりません。
(ただしwarningは出ます。)
Comeau C++の挙動を盲信するとすればVC2008の困った仕様ということになりますが、
これをVC2008でもコンパイルエラーにするにはどうしたらよいでしょうか?
安直に思い浮かぶ解決案としては次の2つがありますが、これは不可として、です。
@class ClassB<T>のTは必ずしもNS_A::ClassAだとは限らないため
friend void foo(const ClassB<T>& arg){std::cout << BOOST_CURRENT_FUNCTION << std::endl;NS_A::foo(arg.mem);} // 今回の主役2
の様に明示的にNS_A::で修飾する訳にはいきません。
AClassB(const T& arg)はexplicit指定されていないということは変更不可。
よろしくお願いします。
friend関数に template<typename T>
あ、コンパイルエラーw
無限再帰になるVCのほうが正しいような気がするけど実際どうなんだろう
template<typename U> friend void foo(const ClassB<U>& arg) { ... } でだいじょうぶかな
960 :
955 :2010/04/16(金) 21:52:22
>>958 Effective C++によれば
Barton-Nackman trick を用いているfoo(const ClassB<T>& arg)
の引数にT型のオブジェクトを渡した場合、
暗黙の型変換が適用されるとあったと記憶しています。
なので私も無限再帰になるVCのほうが正しいような気がしていますが、
あのComeau C++の挙動が間違っているとも思えないんです。
961 :
955 :2010/04/16(金) 22:00:34
>>959 それで解決しました。
ありがとうございます。
スタックオーバーフロー起こすのは実行時だから コンパイルエラーを起こさないのは間違いではないでしょ Comeau C++の方がより親切でハッカーに厳しいというだけで
963 :
955 :2010/04/17(土) 00:22:51
>>962 もしその通りとしますと、「文法的には合法なコードを親切心といっただけのお節介な理由でComeauやg++がコンパイルエラーを下した」ということになります。
すると、次の合法なコードで困る事になります。
…………………………
foo()内が
static unsigned i;
if(!i){++i;処理1;foo(arg.mem);}
else{処理2;}
となっている場合。
…………………………
クソコードなのはともかく、このコードは合法であり、プログラマはその気で書いた可能性が否定できない。(実際問題 無限再帰もしないし本当に書きうる。)
そんな合法なコードを規格ギークなg++やComeauがわざわざコンパイルエラーにするとは考えがたいと思います。
>>963 ごめん。意味がよくわからない
そのコードが合法で無限再帰しないなら普通にコンパイル通るんじゃないの?
スタックオーバーフローを起こさないって事なんでしょ?
>>955 >
ttp://codepad.org/xjXwEurR 名前空間スコープに宣言の無い friend 関数は ADL でしか見つからない、というのは
知ってるんだよね?
それなら NS_B::foo(const NS_B::ClassB<ClassA>& arg) の中での foo(arg.mem) で
発動する ADL の検索対象は NS_A なわけで、 foo が見つからないというのは上記の
ルールに従えば当然なんじゃないの??
>>960 今回の話はBarton-Nackman trickは全く関係ない話だと思うんだが
>>955 ClassAがClassB<ClassA>に暗黙変換されたら大変な事になるだろう
コンストラクタがexplicitでないテンプレートクラス全部が暗黙の変換の候補になるってことだぞ
968 :
955 :2010/04/17(土) 12:01:59
すみません すこし前に起床しました。
>>964 > そのコードが合法で無限再帰しないなら普通にコンパイル通るんじゃないの?
> スタックオーバーフローを起こさないって事なんでしょ?
無限再帰するしないは実行時エラーの話なのでそれには関係なく
そのコードが合法なら普通にコンパイルが通り、
合法でないコードならコンパイルが通らないと思います。
>>962 > スタックオーバーフロー起こすのは実行時だから
> コンパイルエラーを起こさないのは間違いではないでしょ
っておっしゃっていたので、
>>962 氏はVCの仕様も間違いでないと言っていることになります。
すなわち本当はコンパイルエラーにはならないのが標準C++としては正しいとおっしゃっている
ことになります。
一方で
>>962 > Comeau C++の方がより親切でハッカーに厳しいというだけで
ともおっしゃっているので、これはすなわち
「文法的には合法なコードを親切心といっただけのお節介な理由でComeauやg++がコンパイルエラーを下した」
という事を意図されているということだと私は解釈したため、
「文法的には合法なコードをComeauがコンパイルエラーにするとは考えがたい。」
と申し上げました。
969 :
955 :2010/04/17(土) 12:09:59
>>965 全くもっておっしゃる通りです。
私の
> なので私も無限再帰になるVCのほうが正しいような気がしていますが、
が間違いで、
>>965 氏のご指摘の通り、
Comeau C++の挙動が正しいようです。
> NS_B::foo(const NS_B::ClassB<ClassA>& arg)
で可視なfooという名前の関数は
ADLで見つけたNS_A::foo
だけなのですね。
ADLで見つけたNS_A::fooに加えて自身の所属するスコープでfooを探すとNS_B::fooが見つかるかと
思ったのですが、ご指摘いただいた通りNS_B::fooは
> 名前空間スコープに宣言の無い friend 関数
なのでADLが発動していないため可視ではないのですね。
ありがとうございます。
970 :
955 :2010/04/17(土) 12:31:49
>>966-967 お返事ありがとうございます。
Barton-Nackman trickとは関係がありませんでした。
Effective C++を読み返してきました。
お二方のおっしゃるとおりです。
971 :
955 :2010/04/17(土) 12:53:07
今回のケースはCuriously Recurring Template Pattern (CRTP)に関係ないので
Barton-Nackmanとも関係ありませんね。
結局、
ttp://codepad.org/T293nYKr このコードのようにした場合はちゃんと(?)無限再帰しました。
この挙動の解釈としては
///////////////////////////////////////////////////
@foo(a, b); // 今回の主役3
において、
「名前空間スコープに宣言の無い friend 関数は ADL でしか見つからない」
があるが、この場合は第1引数aはNS_A::ClassA型、第2引数bは
NS_B::ClassB型のため両方の名前空間を探して
1. NS_A::foo->コメントアウトされているため存在しない。
2. NS_B::foo->名前は見える。有効。
↓NS_B::fooのオーバーロード解決へ向かう(今回はNS_B::fooの名前を持つものは1つしかないが。)
3. NS_B::fooはNS_B::foo(const ClassB<ClassA>&, const ClassB<ClassA>&)であり、
第1引数をNS_A::ClassA型からNS_B::ClassB型へ「暗黙の型変換」可能であり
かつ第2引数を型変換する必要がない
よってNS_B::foo(const ClassB<ClassA>&, const ClassB<ClassA>&)が呼ばれる。
A@で呼ばれたNS_B::fooの中にもfoo(arg1.mem, arg2)があるが、
同様に実引数arg1.mem, arg2の両方の名前空間を探して
1. NS_A::foo->コメントアウトされているため存在しない。
2. NS_B::foo->名前は見える。有効。
↓NS_B::fooのオーバーロード解決へ向かう(今回はNS_B::fooの名前を持つものは1つしかないが。)
3. NS_B::fooはNS_B::foo(const ClassB<ClassA>&, const ClassB<ClassA>&)であり、
第1引数を型変換する必要がなく、
かつ第2引数をNS_A::ClassA型からNS_B::ClassB型へ「暗黙の型変換」可能であり
よってNS_B::foo(const ClassB<ClassA>&, const ClassB<ClassA>&)が呼ばれる。
///////////////////////////////////////////////////
ややこしいです。
972 :
971 :2010/04/17(土) 12:54:02
× 同様に実引数arg1.mem, arg2の両方の名前空間を探して ○ 同様に実引数arg1, arg2.memの両方の名前空間を探して
>>973 その例ではG()が可視だとか曖昧だとかの議論になっていないか?
>>955 のケースに当てはめるとCall()が可視だとか曖昧だとか
論じないとならないんじゃね?
C++ 0xよりC++03+boostの方が可搬性がありそう
>>975 わかってないな。
Call(Y()) の ADL による検索対象は namespace B になるから、それで見つかる。
「自分の所属する名前空間」が namespace B だから、自分の所属する名前空間も可視
であるように見えているだけ。
>>955 の場合は「自分の所属する名前空間」と ADL による検索対象が異なる。
978 :
974 :2010/04/17(土) 15:13:24
979 :
955 :2010/04/17(土) 17:19:36
みなさんありがとうございます。 つまり私の間違いは 無指定のfoo関数の名前解決をする時に 1.「自分の所属する名前空間でfooという名前を持つ関数をsignatureを問わず探す (見つからなければ外側のスコープへ。)」 2.「引数の所属する名前空間でfooという名前を持つ関数をsignatureを問わず探す」 3.「1と2で見つかったfooという関数に対してオーバーロード解決を行なう。必要ならテンプレート具体化も。」 という原則があるが、その際に 「名前空間スコープに宣言の無い friend 関数は ADL でしか見つからない」 が"より優先するルール"であるということを理解していなかった ということですね。
>>977 ほんとだ…Call(A::X())にしたら通らんかった
知ったかしてどーもすいませんでした
レモンちゃん恥ずかしいです
ところでこれがコンパイルできないのはどうして? namespace ns { class hoge {}; class fuga { friend void foo(const hoge &h) { std::cout << __FUNCTION__ << std::endl; } }; } int main(void) { ns::hoge h; foo(h); return 0; } 引数がns::hogeだからns内のfooが検索されるような気がするんだけどだめだった fooはどの名前空間に所属してるんだろうか?
>>981 2レス前を読もうぜ
>>979 にあるだろ?
「名前空間スコープに宣言の無い friend 関数は ADL でしか見つからない」
と。
>>981 ADL での特別ルールは以下のようになっている
ISO C++ 3.4.2 p3 より
> Any namespace-scope friend functions declared in associated classes are
> visible within their respective namespaces even if they are not visible
> during an ordinary lookup
つまり
△ 名前空間スコープに宣言の無い friend 関数は ADL でしか見つからない
○ 名前空間スコープに宣言の無い friend 関数はその宣言を含むクラスを
"associated class" とする ADL でしか見つからない
ここで "associated class" は、引数自身がクラス型であればそのクラスと、他には
引数がクラス内で宣言されたクラスや列挙型であればその外側のクラス、となっている。
これは 3.4.2 p2 に記述がある。
ややこしいが、つまり別途宣言の無い friend は基本的に呼べないもので、それでも
なんとか演算子オーバーロードの目的でクラス内に定義を押し込むことができるように
特別ルールが残されている、と考えておけばあんまり問題に巻き込まれることはないと
思う。
>>982 書いてないじゃん
>>983 thxです
例外的な規則ということなのね
ということは
>>977 あたりの検索対象がBになるから見つかるというのは正確じゃないんかな
friendはめったに使わないから一連の流れは結構勉強になったぜ
>>984 ADL の検索対象が B になったうえで、 B::Call() が引数 Y() の associated class である
class Y の中で宣言されているので、見つかる。
986 :
982 :2010/04/17(土) 22:06:46
>>987 その場合は普通にNS_Aだけが検索されるから見つからないだけじゃない?
どうでもいいけど、二重否定で規定されると分かりにくいな
>>987 これがエラーになるのと同じ。
#include <string>
template<typename C> void foo(std::basic_string<C> const& s);
void bar() { foo("aaa"); }
関数呼び出しに伴うテンプレート引数の推測では暗黙変換は考慮されない。
991 :
987 :2010/04/18(日) 00:54:42
>>988 「名前空間スコープに宣言の無い friend 関数はその宣言を含むクラスを "associated class" とする ADL でしか見つからない」
の範囲外であり、NS_Bの中身も一応 検索はされ、
namespace NS_Bの中のtemplate<typename T>void foo(const ClassB<T>& arg);
という関数テンプレートが見つかります。
それは
ttp://codepad.org/pMnhCtf7 このようにNS_Bの中に
void foo(const NS_A::ClassA& a){std::cout << BOOST_CURRENT_FUNCTION << std::endl;} // さあどーだ!?
という関数を追加してやればコンパイル&リンク成功ということから分かります。
>>990 ありがとうございます。
なるほど、namespace NS_Bの中のtemplate<typename T>void foo(const ClassB<T>& arg);
という関数テンプレートは確かに見つかってはいますが、
暗黙の型変換の対象になっていないため
「signatureの合う呼び出し可能な関数がないよ!」
ということになるのですね。
なんだか昨日は上級者スレになってたな。 みんな大人になったな。 friendだけに なんつってww
オヤジギャグで締めるとはやるな
次スレは?
うめるか
ume
1000
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。