1 :
デフォルトの名無しさん :
2009/01/11(日) 11:21:38
3 :
デフォルトの名無しさん :2009/01/14(水) 21:19:06
次のGCCで0xはどこまでサポートされるのでしょう?
// / / パカッ //⌒)∩__∩ /.| .| ノ ヽ / | | ● ● | / | 彡 ( _●_) ミ まピョーん☆ / | ヽ |∪| /_ // │ ヽノ \/ " ̄ ̄ ̄ ̄ ̄ ̄ ̄(..ノ
janeの隠し機能 1.書き込みウィンドウを出し半角入力に切り替える 2.Wキーを押しっぱなしにする 3.Wキを押しっぱなしにしながらsageのチェックするところをおもむろにクリック
7 :
デフォルトの名無しさん :2009/01/15(木) 20:29:00
wwwwwwwwwwwwwwwwwwwwwww
次の課題A,Bから一方を選び,そこに書かれている数値について, 問(1) 100.0以上1000未満の数 問(2) 1000以上10000未満の数 問(3) 10000以上の数 はそれぞれいくつあるか数え表示するプログラムを完成せよ. 課題[A] JRAのホームページから左にある「競争成績」をクリックし, 下部にある過去の競争成績(カレンダー)から5阪(12月7日阪神)をクリック, 下のほうにスクロールすると11Rとあるがそこをクリックせずにその行の一番右にある 「最終オッズ」をクリック,その後,「3連単オッズ」をクリック.そこに表示されるページの表について。URLを入力するなどして 他のレースの数値についても同様にすぐに数値を数えられるプログラムにすること。(激難) 課題[B] 課題[A]が難しいので,通常はこちらを解くとよい.次のテキストは課題[A]の数値の一部を コピー・アンド・ペーストしたものである.これを[Ctrl+C]でコピーし,scanfの入力において [Ctrl+V]で貼り付け,[Ctrl+D]を入力すると入力を終え,数え始めるようにせよ.他の数値を入力 するときも,[Ctrl+D]を入力することで入力を終え,カウントできるように. っていうのをやろうと思ったらどういう風にするのがいいですかね
ありがとうございます
wwwwwwww
14 :
デフォルトの名無しさん :2009/01/21(水) 18:41:26
15 :
デフォルトの名無しさん :2009/01/21(水) 18:44:50
真・スレッドストッパー。。。( ̄ー ̄)ニヤリッ
さあ次の質問をどうぞ!
大抵のゲームプログラムはFPSでゲーム速度を管理されてますが、FPSが変動してもゲーム速度を常に一定に保つようにするにはどうプログラムを組めばよいのでしょうか?
スキップフレームといって、 物を動かしたりという処理は常に行うものの (といってもあまりに重いときにどうするかを考える必要はあるが)、 描画が間に合わない時は描画のみをスキップする方法を使う。
>>18 TickCountをつかう。OSの起動からの経過時間を計る比較的分解能の高いタイマーを使って速度を保つ。
真・スレッドストッパー。。。( ̄ー ̄)ニヤリッ
名前がぶっといのれすううう
真・スレッドストッパー。。。( ̄ー ̄)ニヤリッ
真・スレッドストッパー。。。( ̄ー ̄)ニヤリッ
この子何がしたいのかしら
昔このスレでいじめられたんだよ
27 :
停止しました。。。 :2009/02/10(火) 18:14:04
真・スレッドストッパー。。。( ̄ー ̄)ニヤリッ
タスクマネージャ。。。( ̄ー ̄)ニヤリッ
真・スレッドストッパー。。。( ̄ー ̄)ニヤリッ
30 :
テンプレート朝鮮中 :2009/02/11(水) 00:01:08
質問です。 テンプレートクラスを継承しているクラスがあるとします。 継承先のクラスで継承元のメンバー関数の処理の動作を変えたい場合、 特殊化とオーバーライドの両方が使えそうな気がしています。 仮に両方が使用できる場合、メリットとデメリットはどのようなものがあるのでしょうか? template <typename T> class BASE { T t; public: virtual void func() {....} }; ---- オーバーライド ----- class A : public BASE<int> { public: virtual void func() { func2(); BASE::func(); } }; ---- 特殊化 ----- template <> class BASE <int> { public: void func() { func2(); BASE::func(); } };
継承すれば、継承元をインターフェイスとして扱える。 特殊化するとテンプレートの意味がない気がする。
>>30 後者は無理だ。
BASE<int>で特殊化するということは、BASE<int>の実装を乗っ取るということ。
つまり、BASE::func();が自分自身を呼び出す再帰になる。
大本のBASE<int>を使いたいというのであれば、
その中では継承しか手段が残らないな。
33 :
テンプレート朝鮮中 :2009/02/11(水) 03:28:30
回答ありがとうございます。 先輩に、 テンプレートクラスにvirtualをつけるのは何故だ!! 静的ポリモフィズムと動的ポリモフィズムを理解していないんでない!! と言われ悩んでました。(実際にはまだ悩んでいますが・・・) 明日、静的ポリモフィズムと動的ポリモフィズムの違いが明記してある 参考書を貸していただけるとのことなので、再度、勉強します。 勉強しても、分からなければ、もう一度、質問させていただきます。
#define const #define private
CもしくはC++でWEB操作の解説してる本があれば教えてください WEBサイトのページから任意の文字列を取得したり そのページの任意の場所をクリックしたりラジヲボタンを選択したり これらをUWSCというツールで行っていました プログラミングに興味があり今UWSCで行っていることをCもしくはC++でやってみたいと思います 紀伊国屋という大きな本屋さんでC関係の解説書を漁ってみたのですが C言語でWEBページを開くということ自体解説されている本が見当たりませんでした 日本語表記でWEB操作を解説している本を教えてくださいm( _ _ )m .NETやperlやPHPなら簡単だぞって解答は不要です CまたはC++でやりたいです よろしくお願いします
諦めろ。
>>37 標準C / C++には通信の概念自体がない、だからなんか外部のライブラリを利用することになる
.NETがいやならなんか他の使えば?
webページを操作って、CGIってことじゃないのか。 webページを開くって、ブラウザ起動するってことか?
携帯からてす
みなさんありがとうございます 出先からなので携帯からです 39さん 帰宅したら見てみます お忙しい中ありがとうございます 40さん CGIじゃないです ヤフーのアンケートに応募したり 株価のデータ取得して整理したりです 今はUWSCで満足できる操作できています C言語覚えたいので これらの操作をCで行うのが目標です ありがとうございました
真・スレッドストッパー。。。( ̄ー ̄)ニヤリッ
関数のローカル変数はいつ初期化されるのでしょうか? これはOK? void push_back(std::vector<int>& v,int val) { static tbb::spin_mutex m; tbb::spin_mutex::scoped_lock locked(m); v.push_back(val); }
>>44 初めて関数に入った時。
ただし、初期化に副作用が発生しない場合は
プログラム開始時に初期化される可能性もある
(いつ初期化されようが動作に変化が無いので)。
STLつかうと一気に実行ファイルサイズが10倍に?! 環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。 C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの? #include <stdafx.h> 後死ね。 言葉が悪いな。それで教えているつもりか。 まぁヒントぐらいにはなったな。 うむごくろう。
>>36 >>38 Boost.Asioとかソケットとかキーワードを挙げるくらいしてもいいじゃない。
まあウェブページのダウンロードくらいだったら、HTTP扱える高水準なライブラリを探すべきだと思うけど。
となるとcurlあたりか
C++ for Programmersは 糞本です買わないでください
>>44 一応言っておくと、初期化は
>>46 の通りだが
現行C++ではスレッドの概念が無いので
同時にその関数に入った場合どうなるかは環境依存。
52 :
誘導 :2009/02/12(木) 21:47:00
後から立てといて意味分からね
54 :
デフォルトの名無しさん :2009/02/12(木) 22:36:02
C++とC言語では構造体を作るときCのほうでしか必要でないものって何なんだ? あとC++の共用体の扱いとかわからんのだが
struct A { int hoge; }; struct A a; ~~~~~~
そういえば、C++では struct stat xx; ではなく stat xx; と宣言できるのだが、それをやってしまうと 同スコープでのstat()関数の呼び出しでエラーになるんじゃなかったかな。 個人的には、「Cの標準」に含まれる構造体はC++で使うときも struct をつけるようにしている。 いや、statがCの標準じゃないのは百も承知だが struct tm とかの場合ね。 で、同様に、struct stat のように「Cでも一般的に使える」ものもそうしてる。 POSIX準拠のものとか。
>>56 エラーになるから struct stat じゃないとダメ。
struct a;
int a();
a x;
3: error: `a' does not name a type
3: error: extra `;'
Process gcc exited with code 1
C++ の話だぞ?
って、ああ、stat の話か。 stat 関数があるからってことか。
boost::multi_arrayで、以下のようなソースがコンパイルが通らなくて困っています。 どこが間違っているのか教えてください。nの代わりに即値を使うとコンパイルできます。 array_type自体のtypedefはうまくいっているようです。 #include <boost/multi_array.hpp> template <unsigned int n> class Test { typedef boost::multi_array<int, n> array_type; typedef array_type::index array_index; // ここでエラー array_type array; public: Test(){} }; int main () { Test<3> m3; Test<4> m4; } ---- g++ -Wall -g -I /usr/include/boost-1_33_1 -o a.exe multiarray.cpp multiarray.cpp:7: error: type `boost::multi_array<int, n, std::allocator<int> >' is not derived from type `Test<n>' multiarray.cpp:7: error: ISO C++ forbids declaration of `index' with no type multiarray.cpp:7: error: expected `;' before "array_index" gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
>>60 array_type::indexが型だということをコンパイラに教えてやる為にtypenameを付ける
typedef typename array_type::index array_index;
62 :
誘導 :2009/02/13(金) 18:51:30
63 :
デフォルトの名無しさん :2009/02/13(金) 18:58:42
こっちが先だな
64 :
44 :2009/02/13(金) 22:21:20
>>51 サンクス。
やっぱり無理でしたか・・・
関数内で
struct{static tbb::mutex m;}M;
みたいに書ければいいなと思ったけどだめぽでした。
関数外に出すしかないか・・・
65 :
誘導 :2009/02/13(金) 22:36:44
class HAGE { private: HAGE(); ~HAGE(); protected: HAGE(); ~HAGE(); public: HAGE(); ~HAGE(); };
コンパイルエラー
HAGE *leave21 = new HAGE(); HAGE *aderans = new HAGE();
69 :
デフォルトの名無しさん :2009/02/13(金) 23:15:47
class ZURA : public HAGE { };
struct LEAVE21{ /* */ }; struct ADERANS{ /* */}; class HAGE{}; template <typename ZURA_TRAITS=LEAVE21> class ZURA : public HAGE{ /* */}; ZURA<> shokumou;
71 :
60 :2009/02/14(土) 00:56:48
ありがとうございました!
72 :
281 :2009/02/14(土) 15:16:38
73 :
停止しました。。。 :2009/02/14(土) 18:06:05
74 :
デフォルトの名無しさん :2009/02/14(土) 18:49:23
1 名前:デフォルトの名無しさん[] 投稿日:2009/01/11(日) 11:21:38 ^^^^^^^
☆, -──- 、 _____ [, -──- 、 _____] , -──- 、 _____ /_____ \� //⌒ヽ ⌒ヽ `\ |/⌒ヽ ⌒ヽヽ | ヽ / | ^ |^ |- 、 ヽ | / | ヽ |─| l // `ー ●ーU′ \ ヽ / ー ヘ ー ′ ´^V / ─ | ─ ヽ i l \ / _丿 i 二 | 二 | | . \ ` ー ´ / .l \ | / l ! >ー── く ヽ \ | / / / / |/\/ \ ヽ  ̄ ̄ ̄ / / 同じスレではこのままだけど l l | l >━━5━━━━━く 違うスレにコピペするとドラえもんがスネ夫 ヽ、| | ノ / く / ヽ に変わる不思議なコピペ。 |ー───j l (⌒(⌒) / |
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
せめて10分は間隔あけようぜ・・・
え?
83 :
デフォルトの名無しさん :2009/02/16(月) 22:31:59
後発スレで自演厨が暴れてるな
84 :
デフォルトの名無しさん :2009/02/17(火) 01:47:18
イテレータのコンセプトは素晴らしいと思います。 ところで<algorithm>ヘッダのテンプレートはほとんどistreamの入力イテレー タに適用できません。 イテレータにバッファを内蔵し前進イテレータに変換すると適用できると思う のですが、こういったものはすでに作られていないのでしょうか? また、アイデアそのものに問題点はありますか? よろしくお願いします。
>>84 std::istream_iterator
std::istreambuf_iterator
86 :
デフォルトの名無しさん :2009/02/17(火) 02:07:09
>>85 両方ともinput_iterator_tagが指定されています。
forward_iterator_tagを想定するとお考えください。
88 :
デフォルトの名無しさん :2009/02/17(火) 02:44:54
>>87 boostのはたしか、ファイルをすべてメモリー上に読み込むような感じの
ものだったと思います。
若干意味合いが異なります。
ovenはちょっと見てみます。
>>84 要素へのアクセスで、初めて読む部分かすでに読んだ部分かで処理を分けることになるので、
vector などのコンテナに必要な分を読み込んでから処理するのに比べて効率が悪くなりそう。
そのうえで、実際には必要な分を読み込んでから処理すれば十分なことがほとんどになるので
あんまり需要が無いんだと思う。
本当に必要だといえる状況だと言うことなら、興味があるのでどんな場面か教えて欲しい。
90 :
デフォルトの名無しさん :2009/02/17(火) 03:44:01
>>89 入力がある場合すべてにおいて必要になるのではないかと思っています。
>>90 それはないだろ。たとえばテキストファイルを1行ずつ読み込んで処理する場合、
getline() あたりで1行読んでの処理をループすればいい。
92 :
デフォルトの名無しさん :2009/02/17(火) 04:04:38
>>91 入力を解析する必要がある場合すべて。
<algorithm>ヘッダを使用するという前提で。
>>92 その説明だと、vectorとかに蓄えればいいのでは、という疑問が解消されない。
どういう利点があると考えるのか詳しく聞きたい。
94 :
デフォルトの名無しさん :2009/02/17(火) 04:15:40
>>93 ストリームの存在意義についてですか?
いろいろ使い道はあるはずだと思いますけど。
>>94 研究するのは勝手だけれど、具体例を出せないのに意義を語られても困る。
>>94 いろいろと言うならひとつ挙げるくらい簡単だろ。
>>94 ストリームの存在意義など聞いていない。
>84 で挙げてる入力イテレータから前進イテレータへの変換をすることが、
必要な分だけコンテナに読み込んでからコンテナのイテレータを使うことに対して、
どんな利点があるのか挙げろと言っている。
>>84 せっかくだからGoFのデザインパターンを全て調べてみろ
99 :
デフォルトの名無しさん :2009/02/18(水) 02:33:36
>>97 亀レスで申し訳ありませんが、ストリームの存在意義そのものが答えになら
ないでしょうか?
>>99 それしか言えないなら聞き方を変えるけど、一旦コンテナに貯め込む方式の欠点は何?
>>99 そう思うんならお前の脳内にある「ストリームの存在意義」を挙げればいいだろ。
それを聞く前に答えになるかならないかなんて、エスパーでもなけりゃわからん。
一般的なストリームの存在意義といえば、一度にメモリ上に読み込まずにちょっとずつ 処理することで少ないメモリで大量のデータを処理できると言う点があるだろう。 しかし >84 で挙げている方法は「バッファを内臓」することでこの点は失われているように見える。
いろいろ適当。 input_iterator it0; input_wrapper_forward_iterator it1(it0); input_wrapper_forward_iterator it2; // ? find_if(it1,it2,cnd()); it2はどう定義するの?
find_ifはinputでいけるねごめん。
こうか stream st; input_iterator it00(st.begin()),it01(st.end()); input_wrapper_forward_iterator it10(it00),it11(it01); algorithm(it10,it11); stream st; input_iterator it00(st.begin()),it01(st.end()); vector v(it00,it01); algorithm(v.begin(),v.end()); このレベルじゃ意味はまったくないな。
変態だな
ゆとり
C++を使うなら妥協って物も覚えたほうがいいよ
妥協は物じゃないよ
名詞だから物だよ
じゃあ、名詞としての”妥協”を覚えればいいんだな
屁理屈こねないの。
形式名詞はひらがなで書けということですね。
114 :
デフォルトの名無しさん :2009/02/18(水) 22:50:24
::func() って記述を見かけたのですが、::の前って省略できるんですか?
>>114 #include <iostream>
void func() { std::cout << "This is ::func()" << std::endl; }
namespace AAA
{
void func() { std::cout << "This is AAA::func()" << std::endl; }
void aaa() {
func(); // AAA名前空間のfunc()が呼ばれる
::func(); // グローバル名前空間のfunc()が呼ばれる
}
}
>>115 さん
ありがとうございます。
名前空間を念頭に置いてコードを読み直してみます。
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
すみません。 どなたかMPEG Audioのdist10というプログラム使ったことある方いらっしゃいませんか?
>>116 ヒント:スコープの概念。
static const int32_t var = 1; グローバルスコープ
namespace foo { static const int32_t var = 2; } fooスコープ
class hoge { public: static const int32_t var = 3; } hogeスコープ
::varは1
foo::varは2
hoge::varは3
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
122 :
デフォルトの名無しさん :2009/03/13(金) 20:52:41
throw new std::runtime_error("saji");
>>122 newされたstd::runtime_error *
だと!そんなもんthrowされたらまさにサジを投げるしかないな。
125 :
デフォルトの名無しさん :2009/03/18(水) 18:38:05
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
std::sort で std::vector の要素をソートしようとしています。std::sort の第三引数にでたらめな比較結果を返す 比較関数を与えるとvector の要素の一部がおかしな値に置き換わってしまい、場合によってはプログラムが 異常終了してしまう現象に悩まされています。問題を再現するプログラムを用意しました。 #include <iostream> #include <vector> #include <algorithm> #include <cassert> int a[10] = {0, 0, 0, 1, 1, 1, 1, 0, 1, 1}, pos = 0; class ComparisonFunc { public: bool operator()(int i, int j) { return a[pos++] == 1; } }; void main() { int t[] = {3, 5, 1, 4, 2}; std::vector<int> v(t, t+5); std::sort(v.begin(), v.end(), ComparisonFunc()); assert(pos == 10); for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) std::cout << *it << std::endl; } このプログラムを実行すると第3要素の値がおかしくなります。VC++ 2008 Express Edition と g++ 4.3.0 (MinGW) では一応実行が終了しますがIntel C コンパイラ 9.0 だと異常終了します。 環境は Windows XP SP3 (32ビット) です。「でたらめな比較結果を返す比較関数」を考えているのは、 ユーザが比較関数をスクリプト言語で定義できるシステムを作っているからです。operator() メソッドの 中でスクリプト言語で定義された比較関数を呼んで、その戻り値を operator() の戻り値として返す仕組みです。 そのためどんな比較関数が来てもプログラムが異常終了しないようにしたいと思います。どんな対策が 考えられるでしょうか? std::sort が比較関数の異常を検知して適当なところで処理を中断して例外でも スローしてくれたらと思うのですがそこまで面倒は見てくれないようです。
>>127 std::sortに渡すコンパレータは辻褄のあった結果を返さないといけないと仕様で決められている。
そうでない場合の動作は未定義。
つまり、でたらめな結果を返す可能性のあるコンパレータはstd::sortには使えない。
ソート関数を自作するか、コンパレータを検証する関数を追加するしかないだろうね。
いずれにしても矛盾を検知しようと思ったら、O(n log n)では済まないと思う。
129 :
デフォルトの名無しさん :2009/03/20(金) 16:49:42
c++で作られたプログラムを逆アセンブルしてるんですが、アセンブリ言語について質問できるスレってありませんか?
130 :
デフォルトの名無しさん :2009/03/20(金) 17:16:32
C++で書かれたプログラムを逆アセ出来る人ってすごいなぁ。 意味不明じゃね?
逆アセするならそもそもアセンブラ理解しないと・・・。 80x86系統の命令コード表あると思うからそれ見ながら分解していけばいいかと 後単純なプログラムでコードがどうなるかをチェックし続けるっていうのが解析の基本><
133 :
デフォルトの名無しさん :2009/03/20(金) 17:34:18
>>130 ありがとうございました。
>>131 IDA pro とか簡単に逆アセンブルしてくれて、しかもグラフィカルに構造を表示してくれるので
あんまり知識が無くてもなんとなく分かります
しかも無料で使えるし。
ソフト自体が英語だしあんまり解説サイトとかが無いのが辛いですが・・。
134 :
131 :2009/03/20(金) 19:47:12
IDA proってすげーー
135 :
デフォルトの名無しさん :2009/03/20(金) 19:56:39
引数オーバーロードによって戻り値を変えるプログラムが g++ (1)3.3.6と(2)4.2.4で挙動が違います。 実行後 main戻り値が (1) => 2 / (2) => 1 となります。 NS1をNS2に書き換えると両方とも2が戻ります。 どっちの挙動が標準規格的には正しいですか? //以下そのプログラム #include <stdio.h> namespace NS1 { struct HUGA {}; } namespace NS2 { int get(...) { return 1; } template <typename T> int f() { NS1::HUGA huga; return get(&huga); } int get(NS1::HUGA * ) { return 2; } } int main() { return NS2::f<int>(); }
うーん。もしかして、Cのソースがあるものなら、直接アセンブラソース吐かせれば良いんじゃね? バイナリを解析したいのならスマソ。
Visual C++2008では 2 になったけど 実際の動作は1にならないといけないみたいね。 vararg は言語によるすべての型チェックを無効にして 常にもっとも一致した型であることを強制するので 多重定義の解決では自動的に最優先になるみたい。
俺も気になってやってみた。 g++ (GCC) 3.4.5 (mingw special)では返り値は1で、 Borland C++ 5.5.1 for Win32では返り値は2だった。 …つまりg++ 4.2.4はちゃんと正しい進化を遂げているということか。
141 :
133 :2009/03/20(金) 20:54:37
>>136 がっつりexeファイルです。
コマンドプロンプトで動く簡単(そう)なコンパイラがあるので、それを解析してデコンパイラを作ってみたくて・・。
にしても、2ちゃんねるのスレッド検索って、「アセンブラ」とか「アセンブリ」で検索すると結果が出るのに、
「アセンブ」で検索すると出ないんですね。ふしぎ!
(...)の絡む名前解決の定義ってISO/IEC 14882:2003にあるの? もしなければ現段階では鼻から悪魔ってことになっちゃうんだけど
よこから質問なんですが (...) ってどうつかうんですか? void func(int n, ...) みたいのであればstdarg.hのマクロでやるのとは思うんですが (...)みたいな...のみとはなんなんなんですか?
144 :
135 :2009/03/20(金) 21:37:44
試してくれた人ありがとうございます。
>>139 ...をvoid*にしても(2)はやっぱり1です。
ちなみにfの定義を非templateにすると両方とも
1になります。template関数が実体化されるときに
初めてオーバーロードの解決を行うっていう理屈で
あれば(1)が正しいような気もします。
ただそれはあまりにもマクロ的な発想だし(2)が
正しい?
NS1をNS2を書きかえると(2)が2に成るのも謎・・・。
145 :
デフォルトの名無しさん :2009/03/20(金) 23:05:11
>142 もちろんある。 っていうか、SFINAE を使う場合に用いられる場合がある。 >139 そして ... のオーバーロード解決の優先度は最低だ。 >常にもっとも一致した型であることを強制するので これで優先されるのは関数テンプレートの時。 >144 > template関数が実体化されるときに > 初めてオーバーロードの解決を行うっていう理屈で > あれば(1)が正しいような気もします。 two phase lookup でぐぐれ。 dependent name の名前解決は実体化時まで遅延される。 nondependent name の名前解決は通常通り行われる。 get(&huga) は nondependent name なので名前解決は 通常通り行われ、この場合は get(...) に解決されるはず。 > 14882:2003 > 14.6 Name resolution/9 > If a name does not depend on a template-parameter (as defined in 14.6.2), a declaration (or set of declarations) > for that name shall be in scope at the point where the name appears in the template definition; the > name is bound to the declaration (or declarations) found at that point and this binding is not affected by > declarations that are visible at the point of instantiation. > > 14.6.3 Non-dependent names/1 > Non-dependent names used in a template definition are > found using the usual name lookup and bound at the > point they are used.
補足。 >っていうか、SFINAE を使う場合に用いられる場合がある。 Modern C++ Design に優先順位が最低であることがポイントであるとした上で載ってるので 変態 templater にはそれなりに知られたテクニックだと思われ。
む・・・むずいw
149 :
135 :2009/03/21(土) 01:20:21
>146 調べきれてないけど4.2.4の方が(規格的には)正しいような 気がしてきました。 NS2->NS1の書き換えはADLの関係でget(HUGA*)がヒット(2がかえる)。 だからget(HUGA*)を位置を変えずにNS1に持っていっても同様に 2がかえるのを確認しました。 get(void*)とget(HUGA*)をtemplate関数の特殊化とした場合 同様に2がかえる。 => depend name? それ以外の場合(オーバーロードの解決)は純粋に出現 順序で決定されると。 => nondependent name? もうちょっと調べてみます。ありがとうございます。
解決されるときに(...)の優先度が最低になるのが見付からないなぁ ま事実だけ覚えときゃ十分か
>149 「NS2->NS1の書き換え」ってどこ書き換えたの? テンプレート引数 T に依存するかどうかが dependent name かどうかの判断なので、 4.2.4 の挙動もおかしい気はする。 >それ以外の場合(オーバーロードの解決)は純粋に出現 >順序で決定されると。 先に宣言されたものが常に選ばれるみたいに読めて微妙。 >150 13.3.3.2/2
152 :
135 :2009/03/21(土) 02:32:23
>151 > 「NS2->NS1の書き換え」ってどこ書き換えたの? 135のサンプルを「NS1->NS2の書き換え」の間違えです。 まとめると //1を有効 & 他無効 => 2 //2を有効 & 他無効 => 1 //3を有効 & 他無効 => 2 #include <stdio.h> namespace NS1 { struct HUGA {}; } namespace NS2 { int get(void*) { return 1; } // int get(NS1::HUGA * ) { return 2; } //1 template <typename T> int f() { NS1::HUGA huga; return get(&huga); } int get(NS1::HUGA * ) { return 2; } //2 } namespace NS1 { // int get(NS1::HUGA * ) { return 2; } //3 } int main() { return NS2::f<int>(); }
153 :
135 :2009/03/21(土) 02:42:13
補足 152のサンプルは3.3.6では全部2になります。 4.2.4みたいにADLの対象か否かで解決遅延対処になるか 否かってのはなんかしっくりこない・・・。
154 :
127 :2009/03/21(土) 05:46:58
>>128 でたらめな比較結果を返す関数を与えた場合の動作は未定義なんですね。
致し方ないので既知の問題としてドキュメントに記載してユーザに注意
してもらうことにします。ありがとうございました。
比較関数全体をユーザ定義にするんじゃなくて、比較処理はC++で書いて、 条件を(比較結果がデタラメにならない程度に)カスタマイズできるように すればいい気がするなぁ。
for_eachについて教えてほしいのですが、下記のコードでfor_eachの三番目の引数である CPrint()に引数を設定ていないのにveciTableの要素が、void operator()(int iValue) ~へ渡されているのはどうしてですか? #include <vector> #include <algorithm> #include <cstdio> using namespace std; struct CPrint { void operator()(int iValue) { printf("%d\n", iValue); } }; int main() { vector<int> veciTable(3); veciTable[0] = 111; veciTable[1] = 222; veciTable[2] = 333; for_each(veciTable.begin(), veciTable.end(), CPrint()); return 0; }
>>156 CPrint()(veciTable[0]) などのように operator () が呼び出されるから。
158 :
デフォルトの名無しさん :2009/03/21(土) 13:22:33
std::tr1::bindですが、↓がコンパイルできません。 Aのメンバ関数に引数を渡したいのではなくて、X::funcBにAを渡したいのです。 どうすればいいでしょうか。 class X { class A { ... }; void funcA(void) { for_each(container.begin(), container.end(), std::tr1::bind(&X::funcB, _1)); } void funcB(const A& a) { ... } std::vector<A> container; };
>>158 X のインスタンス指定が抜けてるよ。
std::tr1::bind(&X::funcB, this, _1) でいけるんじゃない?
161 :
158 :2009/03/21(土) 13:46:42
>>160 であっさりうまくいきました!
昨日一晩の苦労が…。感激です。
>>159 thisがないときのエラーメッセージは(VC9ですが)
「error C2825: '_Fty': '::' が後に続くときは、クラスまたは名前空間でなければなりません」の後
「テンプレートのインスタンス化 'std::tr1::_Result_type1...' の参照を確認してください」という
bind特有の長いメッセージが続きます。
長文で申し訳ない。
>153
やっぱり 4.2.4 の挙動もおかしいと思う。
インスタンス化時点での名前解決の対象になるのは ADL のみみたいだけど、
そもそも、テンプレートパラメータに依存する dependent name に対するものだけなので。
ぴったりしたケースじゃないけど 4.3.1 に対してこんなバグレポもあがってるので、
gcc の挙動をそんなに信用できないと思う。
ttp://gcc.gnu.org/bugzilla/show_bug.cgi?id=36883 テンプレートパラメータに依存しないものならインスタンス化を待たなくとも結果は変わらない
はずだし、遅延すると通常の名前に対するものと異なる直感に反する結果を与えかねないので、
定義時点で名前解決を行えばいい。
一方、テンプレートパラメータに依存する名前について定義時点のみで名前解決を行うとすると、
制約が強すぎる。例えば STL を使う場合、コンテナのヘッダをインクルードする前にコンテナの要素型と
必要な操作が宣言されていなければならない。
従って、インスタンス化まで名前の解決を遅延したいが何でもかんでも名前解決の対象にすると、
これまた直感に反する結果を与えかねない。
ということで、ADL のみに制限しているという理解。
……なんだが、14.6.4 の規定自体に問題がある気がしてきた。
ADL じゃない lookup はインスタンス化時点では行わないようにも読めるんだが、qualified name lookup も
インスタンス化時点で行われないと、dependent name な基本クラスのメンバにアクセスできなくなるので
そんなわけないと思うのだが。
C++ Templates The Complete Guide では dependent qualified name もインスタンス化時点で名前解決されるって
書いてあるんだが、一方、インスタンス化時点で名前解決されるのは ADL のみという記述も結構見かける。
g++の挙動はおかしいから 有名なソフトじゃ禁止コーディング規約いっぱいあるよ C++のインプリで世界最悪なのがg++だし
164 :
デフォルトの名無しさん :2009/03/21(土) 20:10:57
アンチg++必死だなw
165 :
135 :2009/03/21(土) 20:28:38
>162 つまみ食いみたいなレスになりますが・・・ >gcc の挙動をそんなに信用できないと思う。 私もgccのbugzilla幾つか確認したけどアサインされてないバグって 結構いっぱいありますな。外野があれこれいうのもなんだけどあれで C++0x対応が収束するのやら。 > ということで、ADL のみに制限しているという理解。 そもそもオーバーロードは遅延名前解決の対象になるのか? 152の//3はnamespaceが違うのでget(void*)とはオーバーロードの 関係ではないわけで、そういう風に考えると、名前解決が遅延するのも 自然な気がしてきました(w f()内でget呼び出しがTに依存していないのにも関わらず 名前解決が遅延するのがバグであったとしても、 本来はTに依存させて使用するのが普通で、そのバグを 前提にしたロジックを組まなければ何とかなるかと。
>165 > そもそもオーバーロードは遅延名前解決の対象になるのか? > 152の//3はnamespaceが違うのでget(void*)とはオーバーロードの > 関係ではないわけで、そういう風に考えると、名前解決が遅延するのも > 自然な気がしてきました(w 名前解決(というより照合と呼ぶべきかもしれないが)とオーバーロードの解決は別のステップで、 まず名前の解決を行い、その後、名前解決によって発見された候補関数群から、呼び出すべき関数が 選び出される(これがオーバーロードの解決)。 なので、名前の解決が遅延された時点でオーバーロードの解決も遅延される。 ちなみに、private とかのアクセス制限が確認されるのはこの後。
>>163 >C++のインプリで世界最悪なのがg++だし
いるいる、「絶対○○」とか「世界一○○」とか何の根拠もなしに比較したかのように語る人w
ここの住人は頭がみんな良さそう 名前空間なんて、 松坂大輔 宮川大輔 のようなものとしか理解してないんだがな、俺的には。
よくわからんけど、gccは新しいのでやってくれ。windowsもlinuxも4.3.3以前のは入れてない。
gccについて疑問に感じたのなら、本家のforumが待ってるよ。
>>169 gccの4.x系は、Linux上での動作はいいが、Windows上での動作は問題があるって聞いてるんだが。
だからMinGWも最新安定版はg++は3.4.5なんだと。
(アルファ版なら4.x系もあるだろうが。)
聞いた話じゃなぁ
心を振るわせる話なら信用するのに どうして鼓膜を振るわせる話は信用しようとしないのだ。
質問です ソースファイルAでnewしたインスタンスを 別のソースファイルBでdeleteしたりしても大丈夫なんですか?
インスタンスの実体が対応してれば大丈夫だろ
変な設計だとは思うけどな
コンストラクタをcppに書いて、デストラクタをインラインでヘッダに書けば普通に起こる状況だな
クロスDLL問題ってのとは全くの別物だよね? そもそもどうしてあれはダメなんだろ?
それは、それぞれでnewとdeleteの実装が別物だとうまくいかないという話。 msvcr90.dllですべて統一するとか、shared_ptrのようにdeleteごと渡すとかすればいい。 そして、コンパイラが違うとvtblやRTTIの形式が違うという話へ続く……。
そんな面倒事に悩まされる前に一つのモジュールに閉じ込める工夫に労力注げ…と
182 :
179 :2009/03/24(火) 09:35:57
テンプレートの規則や仕様に 詳しくなれる本ってありますかね?
>>184 嘘つくな洋書で一冊出てるだろ
教えろよ
>>185 詳しくなれるかどうかは別。
詳しく書いてるかもしれないけど。
c++ templatesとか c++ template metaprogramming とか
標準じゃunderflow_error投げる規定は無さそうだな。 >189
191 :
189 :2009/03/25(水) 09:38:25
>>190 そうなのか。
とりあえず作っちゃった謎の例外か?
どうも。
0をboolに変換するとfalse, 0でない数をboolに変換するとtrueになるんだよね? これは分かる。 では falseをintに変換すると0, trueをintに変換すると1 ってのは仕様上正しい? 特に後者が心配でならないんだが、標準で1になることが保証されている?
194 :
デフォルトの名無しさん :2009/03/25(水) 22:47:03
>>193 > 4.5 汎整数昇格
> 4 bool 型の右辺値は,int型の右辺値に変換することができる。falseは,0になり,trueは,1になる。
でも、int値をtrueと比較するのは危険なんだよね。
別に気にするな 引き継いで逃げ切ればOK
if ( int値を返す式 ) { } は正常に動作するけど if ( int値を返す式 == true ) {} とやると意図したとおりに動かない可能性がでてくる 妙なルール。
>if ( int値を返す式 == true ) {} は if ( int値を返す式 == 1 ) {} と同じ動作?
うん。
左辺をboolに変換して比較すれば問題ないのにな 変なルールだよな仕方ないけど
201 :
デフォルトの名無しさん :2009/03/26(木) 21:26:34
201
>>197 C が 0 以外は true と決めてたわけで better C としての
C++ は、従うしかなかったんちゃう?
まぁ、そんな言語は山ほどあるわけだが………
比較とか論理演算とかが結果を0と1で返すから trueをそっちに合わせたんじゃね?
#define true 1 #define false 0 typedef char bool; 昔ありそうな超手抜き実装
手抜き?
Exceptional C++を読むとboolの必要性が説かれている
int値をbool値に変換するのは情報の欠落が生じるけど、その逆は生じない。
だからint型とbool型を比較すると、暗黙の型変換のルールに従って、bool型の方がint型に昇格する。
結果、
>>198 のようになって、意図したとおりに動かなくなる。仕様どおり!・3・
208 :
デフォルトの名無しさん :2009/03/27(金) 21:09:51
C++の副作用に関して良く解らないので教えてください。 int a=0; int b=0; int func(int c){ b=a; return c; } このとき、 func(++a); を通ると、bに1が入ることは保障されますよね? func(a++); この場合はどうでしょうか? bに0が入る? bに1が入る? 鼻から悪魔?
>>208 関数を呼ぶ直前と、関数から戻った直後に副作用完了点がある。
だから、どちらもbは1になる。
>209 すいません。もうひとつ教えてください。 && || ?: , 以外の演算子は副作用完了点ではないんですよね? 自分でオーバーロードした演算子の場合は 通常の関数と同じように関数に入る直前と戻った直後に副作用完了点はありますか?
>>211 ある。
ただし、最初にあげてる演算子をオーバーロードした場合、
組み込み演算子と違って、オペランドの評価順序が不定になったり、
ショートサーキットでなくなったりするのには注意。
有難うございます。 たびたびすみません。 「オペランドの評価順序が不定になる」とは何ですか? 組み込み演算子でも一般的に不定だと思うのですが、 オーバーロードによって不定でなかったものが不定になる場合があるのですか?
あ、 組み込みの && || ?: , 演算子の評価順序のことですね? 自己解決しました。
printfで64bit値(u_int64_t)を表示したい。 32bit環境では %llu 64bit環境では %lu 両対応でスマートな解決法ってないものだろうか? define拾ってきて切り替えるくらいしか思いつかない
unsigned long long にキャストしていつでも %llu で表示する
VCとかは%I64uだったような defineで切り替えるしかないんじゃね?
末尾にLがついてるのってlong int だよな?
>>216 その手があったか!
思考がループしてそこまで考え付かなかった。 thx
C99かC++0xでは<inttypes.h>のPRIu64を使う
>>220 それだと、uint64_t使えというところから始めないと。
222 :
193 :2009/03/28(土) 19:54:02
>>194 あまりにもな遅レスすまんかった!!
ちょっと私用が。。。
汎整数昇格 了解しました。
ありがとう。
最近C++の勉強をはじめた者なんですが、n個のデータを打ち込んで それらの平均値や標準偏差を求めるプログラムを打ち込んだところ、 .\例題2.1.cpp(10) : error C2679: 二項演算子 '>>' : 型 'const char [2]' の 右オペランドを扱う演算子が見つかりません (または変換できません)。 というエラーが出てしまったんですが、なにが原因かさっぱりわかりません。 いつもと同じように打ち込んだつもりなのですが、原因分かる方いませんか?
224 :
デフォルトの名無しさん :2009/03/28(土) 23:33:21
せめて例題2.1.cppの10行目くらい見せろよ
cout<<"nの値は?"; cin>>n>>"\n"; こうなっています。見たところどこにもミスはないと思うのですが・・・
>>225 cout<<"nの値は?"; cin>>n;
>>225 場合によって意味が変わるけど<<は出力、>>は入力
cin >>n
nに入力された値を入力
n>>"\n";
次に入力された値を"\n"に入力
だぞ?
おかしいだろ
>>226 ああ、なるほど!入力と出力の指令が混同してましたね(汗)
こりゃ動かんわ・・・どうもありがとうございました!!
以下のようなコードを見たのですが、 これってC++のルール上、 ((T*)NULL)->function() は安全にコールできるんでしょうか? class T { void function(){ if (this == NULL){ return; } メンバにアクセス } } function() が virtual だとしたらヌルポ例外ですよね?
>>299 C++にnull_pointer_exceptionなんて気の利いたもんはない。多分OSがそのプロセスを殺そうとするだけだろう。
経験則ではメンバに触れなければ落ちないけど規格で決まってる訳ではないだろうからお勧めしない。
>>229 ((T*)NULL)-> が現れた時点で未定義動作になる。関数の中身は関係ない。
((T*)NULL)->function() このfunction()をstatic関数にしてみるとどうだろう? 有識者のご意見を聞きたい。 class T { public: static void function(){} }; int main() { ((T*)NULL)->function(); return 0; }
未定義。だいたいコンパイル通るのか
通るよ
237 :
234 :2009/03/29(日) 00:49:17
ちゃんと質問する前にコンパイル済み。
通ったよ。g++ね。
C++では
(T*)NULL
自体は未定義じゃないよね?
>>232 さんが言っているように
>((T*)NULL)-> が現れた時点で未定義動作になる。関数の中身は関係ない。
なのだとしたらstaticだろうが何だろうが確かに未定義になるのだろう。
が、static関数なら実質的にグローバル関数扱いなのではと思っているので疑問だった。
staticなメンバ関数はstaticなメンバ変数にしか触れることができないじゃん。
>>236 チェックしてくれてありがとう。
c++でcキャストは使うべきじゃないよ。 >229
今更そこに突っ込む不毛さ。
class Test { public: void func( void ){ std::cout << "test"; } }; int main( void ) { static_cast<Test*>(NULL)->func(); return 0; } メンバ変数に触れなければこれもコンパイル通って動きそうだけど さすがに未定義か?
ほぼ全ての環境で動くだろうけど未定義。 メンバ関数の呼び出しはつまるところ暗黙の引数thisを含む関数の呼び出しにすぎない。それがNULLであったとしても関数を実行するコードはあるので実行はされる。 でも未定義。
243 :
237 :2009/03/29(日) 01:07:21
>>240 メンバ関数に触れていても通るよ。
コンパイラにはNULLかどうかなんてコンパイル時に分からない。
全く問題無く通り、実行時に鼻から悪魔が出て来ることとなる。
ところが
>>237 が言っているstatic関数になると話は別じゃね?
俺はstatic関数に詳しいとかいうわけじゃないから知らんけど、
グローバル関数に無理矢理クラス内というスコープつけたものという認識。
>>244 未定義動作になるのは、オブジェクトを指していない参照に対して単項 & や sizeof など特殊な
ものを除く演算子を適用した場合はいつでも。
アロー演算子 -> の右にあるのが何だとか関数が static だとかそんなのは関係ない。
246 :
244 :2009/03/29(日) 01:27:35
247 :
237 :2009/03/29(日) 01:33:32
delete NULL; ってのがあったな。めずらしく安全な例で。
>245 ポインタだからいいんじゃね? 4.10 Pointer conversions (snip) A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of pointer to object or pointer to function type.
>>248 p->x は (*p).x と定義されている。
キャスト演算子だけなら問題ないってことだろ。 ((T*)NULL);
std::vector<ポインタ型> v; というのがあって あるタイミングで v.push_back(アドレス); これやるとmemoty.stlの__rw_basis::data()で落ちるんです。どうやらタイミングとかが関係するみたいなんで どなたかエスパーお願いできないでしょうか?再現ができなくて申し訳ないんですが・・・
環境書いてよ。それだけだとRogueWave製の標準ライブラリを使ってることぐらいしか分からない。
>>250 それはあたりまえ。だれもそんなところ問題にしていない。
__LINE__みたいに関数名表示するマクロありませんか?
標準ではC99で__func__。 コンパイラ拡張なら色々。
ちなみにマクロじゃないぜ。
258 :
デフォルトの名無しさん :2009/03/29(日) 17:40:26
戻り値が指定されてる関数で、 関数の最後にreturnが無くても 関数の最後まで到達しないなら C++の規格上は正しくコンパイル、実行できることは保障されますか? たとえば以下のような記述は問題ないですか? int a(int n){ if (n){ return 0; } else { return 1; } } int b(int n){ if (n*n>=0){ return 0; } } int c(int n){ while(1); }
259 :
デフォルトの名無しさん :2009/03/29(日) 17:45:52
全部問題あります。
>>258 戻り値が指定されてる関数で、
関数の最後にreturnが無くても
関数の最後まで到達しないなら
C++の規格上は正しくコンパイル、実行できることは保障される。
ただ、b() はその条件を満たしていない。
nの値により条件を満たすのでは?
値によらないだろw
264 :
デフォルトの名無しさん :2009/03/29(日) 19:56:38
仮に int b(int n){ if (n*n>=0){ return 0; } assert(false); return 1; } と書いても鼻から悪魔が出るだけだな # スレ違いっぽいが
俺は、例えばn=1000000って意味に取った
ああ二乗してるから必ず正なわけか
でもオーバーフローした時に悪魔だな
aもbもcも書いたとおりにコンパイルも動作もできるし と思っているのだが,bはNGなのか?
bを実行したとき、nの二乗がintをoverflowしたときは鼻から悪魔が出る それ以外はコンパイルも動作もOK
int b(int32_t n) {if (int64_t(n) * n >= 0) return 0;} なら大丈夫かな?
271 :
デフォルトの名無しさん :2009/03/30(月) 12:38:17
大丈夫も大丈夫じゃないも、問題が起きそうな記述に警告を出してくれない方がよほど大丈夫じゃない
本当に簡単に鼻から悪魔るんだな もうsqrt(abs(n)) <= INT_MAXとかoptionalとか使って部分関数として定義するしかないのか
273 :
デフォルトの名無しさん :2009/03/30(月) 20:07:59
コンマ演算子は副作用完了点で、 関数の引数のコンマは副作用完了点ではないのは理解してますが、 初期化子のコンマは副作用完了点でしょうか? たとえば、以下のコードは正しく動きますか? struct T { int a,b; ...... }; int f(); void g(){ T t={ f(), t.a }; ....... } void h(){ int a[2] = { f(), a[0] }; ....... }
274 :
デフォルトの名無しさん :2009/03/30(月) 20:27:52
あと、同じ型で複数の変数を定義する時のコンマは副作用完了点でしょうか? たとえば、以下のコードは正しく動きますか? void g(){ int a=f(),b=a; ...... }
継承した親クラスの実体を参照するメンバ変数を、なるべく無駄なメモリを消費せずに 実現したいのですが、よい方法はないでしょうか? メンバ関数を使えばよいのは承知しているのですが、できれば "()" を書かずに済ませたいのです struct coord { int x; int y; } ///< これを親にしたい class state { coord position; ///< この部分をメンバ変数として持つのではなく親から継承したい coord velocity; void foo(); } extern void bar(coord& param); void state::foo() { bar(position); bar(velocity); } 現在は親の参照を返すメソッドを作り、マクロでごまかして無理矢理実現しています しかしマクロがソース全域に作用してしまうのでなんとかしたいのです class state: public coord { coord velocity; coord& position() { return *this; } ///< 参照を追加 const coord& position() const { return *this; } ///< const 参照を追加 #define position position() ///< 強引にマクロ…関係ない部分まで作用してしまうのが難点 void foo(); ///< foo() 内で親の実体を *this ではなく position と書いてアクセスしたい! } 試しにこんな風に書いてみたのですが、うまくいきませんでした class state: public coord { coord velocity; const coord& position; /// こんな感じの参照をメモリ消費なしで定義したい state(): position(*this) {} /// ここでエラー orz void foo(); }
>>275 何かいろいろとアレな気がするが、少なくとも私の環境では
struct coord { int x; int y; };
class state: public coord {
coord velocity;
const coord& position;
state(): position(*this) {}
void foo();
};
というコードはコンパイルが通る。
エラーが出るというなら、コンパイラの名前とエラーメッセージを書いてほしい。
あと、クラス定義の最後のセミコロンを忘れていないかね?
セミコロンを忘れてしまい申し訳ないです。 コンパイラはVC++6.0 SP5+プロセッサパックでエラーメッセージは以下の通りです error C2758: 'position' : オブジェクト コンストラクタの初期化リストで初期化されませんでした。 'position' の宣言を確認してください。 最近のコンパイラではこのソースでも動くとのことなので、こちらでもコンパイラを変えて 試してみようと思います。
>>275 なんか、やりたい動機がよくわからんのだが・・・。
stateからxは、継承関係にあるから当然そのまま参照できるよね。
void foo() { x = 1; }
親クラスのメンバであることが明示されたコードを書きたいってこと?
それなら
void foo() { coord::x = 1; }
これでいいと思うんだけど。
何度も書き込んで申し訳ありません、VC6でもコンパイルできました warning C4355: 'this' : ベース メンバ初期化リストで使用されました。 エラーではなくワーニングが出ていたのが原因でした。お騒がせしました
>>278 foo()内部で bar(*this); ではなく bar(position) と書きたい、というのが動機です
>>280 あー、何となく気持ちはわかる。でも俺がやるとしたら
#define This (*this)
的な方法を選ぶかなぁ、実際にはやらないだろうけどww
ありがとうございます。説明不足で申し訳ないです。動機はもっと正確に書くと、 クラス同士が親子関係を持っていなかった時点と同じ可読性(できれば完全に同一の記述)を クラス間に親子関係を持たせた後も維持したい、です 1. foo() 内部で bar((coord&)*this) や bar(position()) と書かずに以前のまま bar(position) と書きたい 2. foo()の外部で state a; coord b; a = b; a.position = b; 上記のように書いた場合に両者のコンストラクタを区別したい 区別のために ((coord&)a) = b と書きたくない 3. 親を参照するメンバ変数 position& が最適化後に実体を持たずに消えてほしい (調べてみたところ、VC6では消えませんでした) マクロを使うことで制限つきながら上記3つは実現できたのですが マクロの範囲が広すぎて関係ない部分まで影響が出るのが難点でした 要はほとんど好みの問題なのですが、どんな泥臭い方法でもいいので、 A. 無駄なメモリを消費しない自分自身(親の実体)への参照を定義するか、 B. プリプロセッサに頼らずにメンバ変数の記述でメンバ関数の呼び出しが行われるようにしたいのです もしBが可能なのであれば、例えばコンストラクタがあってunion化できないメンバ変数へ 部分的なアクセスを行う擬似unionのようなことも(C++の理念的にどうなのかは別として)できそうです
マクロは全力で避けろ 継承は is a の関係 包含の方が多くの場合適切 なぜ男なんだ
>>282 なんか、説明聞いたらさらにツッコミたくなってしまったw
foo() の汎用性を持たせたいなら static foo(coord&) にして
メンバの場合
foo(*this);
変数の場合
coord c;
foo(c);
と俺はしたくなる。
ちなみに、bar((coord&)*this) は冗長なキャストだけど、わざとそう書いたんだよね・・・?
285 :
デフォルトの名無しさん :2009/03/31(火) 02:45:50
>>285 少なくともVC++8で試してみたらコンパイルは通って動作も期待通りだった。
C++の言語仕様として保証されているものかどうかは知らん。
C++かCでデータ構造関係のアルゴリズムが詳細に 掲載されている本というとどんなのがありますかね?
>>287 ありがとうございます。
リンク先は非常に参考になりました。
すみませんが、依然
>>274 がわかりません。
おわかりでないでしょうか?
> 挙げられた例では未初期化のオブジェクトを参照しているので、
これに
>>274 も含まれていたりしますか?
英語版wikipediaでは、
> At the end of an initializer; for example, after the evaluation of 5 in the declaration int a = 5;.
とありますが、
an initializer がどういう単位か分かりません。
MSDNでは、
> The end of a full initialization expression, such as the end of an initialization in a declaration statement.
とありますが、a full initialization expression が、
int a=5, b=a*10, *c=&a, &d=a;
のa,b,c,d それぞれなのか、この文全体なのかわかりません。
よろしくお願いします。
std::stack<std::string> s; とした場合、 s.push(~)はsの中に~のコピーが出来る仕様でしょうか? つまり std::stack<std::string> s; std::string *p=new std::string; s.push(*p); delete p; としたとしても、スタックsは何の影響もなくs.top()とかしていいんでしょうか?
多分だめじゃよ、とーまんこー。 コンテナは値セマンティクスを要求するから 値として振舞わないものは入れられないのじゃ。 入れるならしぇあぽを入れなされ。 そして、そのプログラムは「依頼人のいない弁護士」を 保持することになる。
>>290 stackにpushした時点でstringがstack内にコピーされるから問題ない。
293 :
191 :2009/03/31(火) 21:57:27
あぁ、ほんとだpushの引数に * が付いてた^^
すまんこ学園。つまり
>>292 が正解。
294 :
290 :2009/03/31(火) 22:19:18
すまんこ・・・
トライ木ってどんな木なのでしょうか? データ構造がいまいちわかりません
たとえばABC,ADE,ABDの三要素のトライ木を書くとこんなかんじ A-B-C | |-D | |-D-E 左端のAが木のトップで右側が子要素な。 親から末端ノードまでの要素を連結すると登録した要素になる。 ツリーの深さはキー長に比例するけど1回辺りの比較が超軽いのが特徴。 これを改良したのにパトリシア木とかあるけど詳細は略
>>298 データ構造をどう表現していいの?
ノード毎にオブジェクト作るとかアホな
データ構造しか作れそうにないんだけど
意味あるのですかね?
N木使えばいいやん
301 :
デフォルトの名無しさん :2009/04/01(水) 00:47:31
ノード毎にオブジェクト作っていいんじゃないの。
そういや昔 map<string, map<string, map<string, map<string, string> > > > みたいなの扱ったことあったなぁ、デバッグしててわけわかんなくなったりしたけどw これもトライ木と言え・・・ないか。
>>299 利点としては多数のキーが格納されてるときに、
一般的な二分木と比べてキーの探索が速いのと、メモリの無駄が少ない事
ただ、キーが文字列みたいに分解可能であることを要求するから
データの制約は2分木よりあるからトライ木って結構使いどころを選ぶんだよなー
トライと聞いてスクールウォーズを思い出した。
>>289 int a = 5;
↑この宣言において、 "initializer" (初期化子)は "= 5" の部分。
あとはわかるよね?
MSDN の "full initialization expression" は規格中に現れる用語では
ないのではっきりしないけど、おそらく上記の宣言における 5 に対応するもの
だろうと考えられる。
>>306 わかりました。
有難うございます。
>>307 規格書は結構高かった気がするので....
そのうち手に入れます。
>>308 > 規格書は結構高かった気がするので....
いや、だからダウンロードできるドラフトを読めば、って話なんでしょ。
買うといってるのを止めるわけじゃないけど。
規格書いくらだっけ?7万くらいだっけ 昔興味本位で買おうとしたけどあまりにもバカ高くてやめた覚えがある
つーかJISの規格書って、なんでまたあんなに高価なの? JISって営利目的の機関なの? 勝手に幻滅する俺がいる。
甘い汁をすすってる奴らがいるってことだろう
嫌なら買わなくてもいい
314 :
デフォルトの名無しさん :2009/04/01(水) 19:44:34
Cなどの規格はともかく、全国で数百冊しか売れない本ばかりだから内容もふくめて高いのは当然
俺は別にC++で生計立ててるわけじゃないから買わない。 俺も甘い汁をすする側になりたいものだ。
うんこした後にさ、ティッシュに血が付いてると、 この世の終わりみたいな気分になるよね。 JISの規格書が高いのもそのせい。
>>316 生々しいな
俺まだ血が付いてたことはないんだけど。。。
俺はもう慣れたけどな。 拭く前からわかるんだよね、硬さで。
いそいで拡張作業または増強作業にもどるんや
ツリーの圧縮って どうゆうアルゴリズムあるのLZ法とか 今でも使うの?
"ツリーの圧縮"の検索結果 12 件中 1 - 12 件目 (0.22 秒)
>>320 流れから細部を省略しているのかもしれないけど
どれのことかわからん
>>322 うちの職場にいる!! そんな感じの使ってる人!!
俺の脳内ではワッシャと呼んでいる。
15くらいからケツ拭いたら必ず血がついてるわ 別に普通じゃね?
おまる?
いつのまにかG++相談室になってる
>>326 どういうこと?
(俺が空気読めなくて)意図を察せないんだが。
328 :
317 :2009/04/01(水) 23:42:49
>>324 俺、今23だけど大丈夫なんだが・・・。
マクドの硬い椅子で膝組んだり色々涙ぐましい回避策取ってる女とか ちょっとかわいそうに思うよ G
トイレの水が赤く染まったときはさすがにやばいかもと思った 穴あきクッションって効くのかな?
>>331 脅すつもりはないが、あまりに量が多いようなら内臓由来の可能性もあるから
一度診てもらったほうがいいぞ。
甘い汁って、すするものなの?
下半身から滴る赤いしるをじゅるりスレ
案件でJava使ってサイトつくるよって言われて, JBossとJSPとJava/CGIどれ選べば星界?
C++/CGIが正解
>>287 int i = i; は、値が不定じゃなくて未定義動作。
>>340 最新のは規格書の代替にならないんじゃ?
343 :
340 :2009/04/02(木) 09:22:07
>>342 現行規格の代替なら 2003 年の直前のやつをダウンロードすればいい、
と思ったんだけど、あんまり古いのは無いみたいだった。 340 は嘘ね。ごめん。
ダウンロードできるいちばん古いのは 2004 年の N1577 だった。
途中で公開の方針が変わったのかな?
私はJISのサイトで2003年の規格の日本語訳が無料で読めるんでそれだけで十分ですが 英語の規格書を読みたい人ばっかなんですよね?
日本語でいいです。
検索できないし改頁潰れてるしときどき訳間違ってるし脚注抜けてるし JISなんていりません
347 :
デフォルトの名無しさん :2009/04/02(木) 21:42:18
検索できないのは板杉だな
私検索できるPDFもってるけど。
>>348 それってダウンロードすると白く塗りつぶされるんでしょ。
>>349 うん。
でもクラック済み。
検索も印刷も普通にできるよ。
351 :
デフォルトの名無しさん :2009/04/02(木) 22:20:03
昔はクラックなんかせずとも正規購入できたのに
今のJISのサイトのは検索できるよ ただし日本語とアラビア数字に限る。アルファベットは不可。何でこうなったんだろうね… おれはJISのでもいいと思うけど、URLが決まらないのでこういうところで紹介するには不向きだと思う テンプレに手順を書いてくれればいいんだけどね
実際に、ライブラリレベルじゃなくて、アプリKションレベルのものを書くとき、 mediatorパターンみたいな感じになっちゃって、 mediatorに相当するクラスのヘッダを、他のクラスから必ずincludeするような設計になっちゃったんだけど、 これって間違ってる? C++の話題とはズレてごめんね>禿
検索できないってどういうこと? 私はLinux用のアクロバットリーダーのバージョン8を使っていますが検索機能付いてます。 JISの文書自体は文字単位で範囲選択できるので検索できない理由がわからないのですが?
JISのPDFは本文の文字の一部が画像になってる
どこですか?
いやいや、少し前のは全ページ画像だった。その代わりダウンロードしても見られたけど。
どういうこと?ってここで言われてもなぁ…JISに言ってくれよJISに
359 :
デフォルトの名無しさん :2009/04/02(木) 23:00:37
> ※最新バージョン9の使用は今しばらくお待ちください。 オマエ、ソレハナイダロウ
>>359 俺もそれ思ったwwww
えええええええ!?!?ってオモタ
今日は肛門疾患の話はないのか、寂しいな。
痔には乙痔湯! 喪前らも、服用しる
memchrと strchrって何が違うの? 長さが既知だとすると性能一緒?
365 :
デフォルトの名無しさん :2009/04/04(土) 00:47:26
366 :
デフォルトの名無しさん :2009/04/04(土) 00:54:00
367 :
デフォルトの名無しさん :2009/04/04(土) 00:54:07
>>366 '\0' と NULL をごっちゃにするな。
369 :
デフォルトの名無しさん :2009/04/04(土) 01:06:43
イヒヒ
null character
strchar 一文字単位で文字列終了文字判定 memchar カウンタがアップの判定だけ どんなコードに落ちるかはCPUのアーキテクチャ次第
少なくともmemchrがstrchrより遅くなることはないから 出来る限りmemchrを使う 基本的にmem○○とstr○○は常にmem○○優先
いいえ。
memchrの方が2倍ぐらい遅いよ
二倍なんてもんじゃないよ
FreeBSD 7.1-STABLE、Celeron 700MHz(i386) で計測したらstrchrよりmemchrのほうが5パーセントほど 遅いという結果になりました。 どちらの関数もアセンブリ言語で書かれてあります。
std::string str="hoge"; const char * const p = str.c_str(); こういう使い方ってして良いの? このケースではまあ最初からp="hoge"とすれば良いことになるけどもね。
c_strは使ってはいけない
>>382 str.c_str()がだめってこと?
どうして?
384 :
381 :2009/04/04(土) 19:17:19
std::string str="hoge"; const char * const p = str.c_str(); str="piyopiyo"; const char * const q = str.c_str(); std::cout << reinterpret_cast<unsigned long>(p) << "\n" << reinterpret_cast<unsigned long>(q) << std::endl; 結果:pとqが違う値。 このようにstrが変わった時にpが無効になってる可能性はあるよね。 あるサンプルソースで似たようなコードがあって疑問だった。
386 :
381 :2009/04/04(土) 19:18:31
c_str() や data() が返すポンストコインタは
次に const でないメンバ関数が呼ばれるまでの間のみ有効という「時限式」なので
ポインタは保持しないほうがいいよっていうのが一般的な話。
わかってやるなら
>>381 自体は違法じゃない。
388 :
381 :2009/04/04(土) 20:40:56
>>387 分かりやすい説明ありがとう!
理解した。
std::string str(""); ってやってるヤツがいるんだが std::stringはデフォルトコンストラクタでは空文字列にしてくれることが仕様上保証されているんだよね? つまりstr("")は無駄だよね?
390 :
デフォルトの名無しさん :2009/04/05(日) 01:12:17
>>389 お前のようにデフォルトコンストラクタの仕様を知らないアホにも空文字列で初期化されることがわかるから無駄じゃない。
速度は実測が基本。
優秀なコンパイラで強い最適化オプションを指定していると、勝手にそれくらいは修正してくれないだろうか?
そもそも速度を気にするようなところでstd::stringを使うのが間違い。 動作速度でstr("")が無駄と言う奴は馬鹿。
>>394 優秀じゃなくてもふつうそれくらいするよ。
>>397 何がおかしいの?
具体的に言ってみ、お前の脳で言えるのなら。
>>399 str("")とデフォルトコンストラクタでは速度に差が無いから
>>391 はウソ。
以上。
もうお前ら全員安価つけてやれ、ホント、マジで頼むから。
5レス連続でアンカが付いている件について
>>402 いや、その前も含めて全部。
・・・と思ったら俺自身安価付けてなかった
ごめん吊ってくる。
>>400 残念ながら同じバイナリに落ち着かない以上、速度に差がないとはいえない。
出直しておいで坊や。
何か必死だな。
407 :
デフォルトの名無しさん :2009/04/05(日) 02:24:22
仲良くしなよ
文字列リテラルの使いまわしを認めないコンパイルオプションつけたらちょっとバイナリが増える・・・・・かな?
>>404 同じ()バイナリ()落ち着く()
スイーツ()ですか
結論 str("")は無駄ではない。
411 :
デフォルトの名無しさん :2009/04/05(日) 02:58:05
ねーよ
std::stringはデフォルトコンストラクタでは空文字列にしてくれることが仕様上保証されているんだよね? なんて醜態晒すくらいなら std::string str(""); と書く方がよほどスマート。
次期規格ではstring()はstring("")に委譲する実装になるだろうから そうなれば本当に速度に差はなくなるだろう 今は知らん
普通に、こう考えろ char* str = NULL; char* str = ""; 同じか?w
全角のアルファベットを打つ奴はゆとり
全角ってなんですか?
417 :
デフォルトの名無しさん :2009/04/05(日) 08:47:43
>>353 > mediatorに相当するクラスのヘッダ
の中では前方宣言するのが吉。
そうしないと冗長すぎる依存関係になってしまう。
アプリケーション全体が10kくらいなら気にしないのも有りかも。
C言語でWEB操作したいです 証券会社にログインして株価を監視して自動売買が目標です まずはC言語でWEBページを開く方法を教えてください
>>413 > 次期規格ではstring()はstring("")に委譲する実装になるだろうから
なんでそんなとこ変わるの?
>>418 C Web Download をgoogle検索
あきらめろ
422 :
デフォルトの名無しさん :2009/04/05(日) 13:32:16
デストラクタはpublicで宣言するものだよね? privateで宣言すると、 まあ普通にコンパイルエラーになるんだけど、 特殊な状況でprivateなデストラクタってある? なんか俺の知らないイディオムでありそうな気がしてきたんだが。
deleteをオーバーロードしてるとかじゃないとコンパイルすら通らなくね?
425 :
423 :2009/04/05(日) 18:18:06
>>424 そう、通らない。
でも例によってC++は深遠だからさ、
俺が知らないだけで便利なイディオムがあったりするかな~って興味が出てきた。
とりあえずnewで生成してみろよ
自動変数や静的変数としては使えないが、newすることは出来る。 deleteはクラスのメンバ関数から出来る。 だから、使えないことはない。具体的にどう役立つのかは分からんが。
428 :
423 :2009/04/05(日) 18:25:28
あ~、newで作るのか。 なるほどね。
Effective C++にて const char* const authorName="ScottMeyers";//方式1 const std::string authorName="ScottMeyers";//方式2 この2つが紹介されていたんだけど、結局どっちが良いの? 本によれば方式2の方が良いよ的な書き方されていたんだけど、どうして方式2が良いのか分からない。
class MyClass{}; として、 boost::shared_ptr<MyClass> p(new MyClass); だと大丈夫なのに boost::shared_ptr<MyClass> p=new MyClass; だとダメなのは何故でしょうか? 私は宣言時に (初期化値)とするのと =初期化値とするのは 等価にコンストラクタを呼び出す物だと思っていたので驚きました。
>>430 boost::shared_ptr<MyClass> p=boost::shared_ptr<MyClass>(new MyClass);
>>430 コンストラクタに explicit がついていると
> boost::shared_ptr<MyClass> p=new MyClass;
は不可能になる。
例えば
class MyClassA {
MyClassA(int n);
};
class MyClassB {
explicit MyClassB(int n);
};
となっていた場合、
MyClassA a(3); // OK
MyClassA a = 3; // OK
MyClassB b(3); // OK
MyClassB b = 3; // NG
となる。
また、
void myFuncA(MyClassA a);
void myFuncB(MyClassB b);
という関数があった場合
myFuncA(3); // OK
myFuncB(3); // NG
となる。myFuncB(MyClassB(3)) は可能。
>>431 それはキャストですよね。
つまりキャストしないとダメなんでしょうか?
なぜですか?
…あ、もしかして
boost::shared_ptr<MyClass>のコンストラクタが
explicitになっているということでしょうか?
434 :
433 :2009/04/05(日) 18:43:20
>>432 すみません。
再読込してませんでした(> <)
失礼致しました。
explicitですね。
もうちょっと勉強して出直してきます。
436 :
432 :2009/04/05(日) 18:44:11
ごめん、
>>432 の例だとコンストラクタがprivateになってるね。public: を付け足して読んでほしい。
437 :
433 :2009/04/05(日) 18:51:15
>>435-436 ありがとうございます。
>newしたらすぐにスマートポインタにセットさせるのが基本。
これがRAIIってやつでしょうか?
>>423 カスタムデリータを使うときにデストラクタをprivateにして隠して、カスタムデリータ外から勝手に呼べなくする。
439 :
423 :2009/04/05(日) 19:03:36
>>438 あーなるほどね。
やっぱあるんだ。
サンクス
仮想関数として指定するキーワードvirtualは、どれだけ付けるのが正しい? 例えば class Base { public: virtual void m_func(){std::cout << "Base m_func!" << std::endl;}; Base(){std::cout << "Base Constructor!" << std::endl;}; virtual ~Base(){std::cout << "Base Destructor!" << std::endl;}; }; class Derived : public Base { public: void m_func(){std::cout << "Derived m_func!" << std::endl;}; Derived(){std::cout << "Derived Constructor!" << std::endl;}; virtual ~Derived(){std::cout << "Derived Destructor!" << std::endl;}; }; class Derived_Derived : public Derived { public: void m_func(){std::cout << "Derived_Derived m_func!" << std::endl;}; Derived_Derived(){std::cout << "Derived_Derived Constructor!" << std::endl;}; virtual ~Derived_Derived(){std::cout << "Derived_Derived Destructor!" << std::endl;}; };
441 :
440 :2009/04/05(日) 21:06:11
んで呼び出す時は
void foo()
{
Base* p=new Derived;
Base* q=new Derived_Derived;
Derived* r=new Derived_Derived;
p->m_func();
q->m_func();
r->m_func();
delete p;
delete q;
delete r;
}
このように、俺はBaseのm_func()にしかキーワードvirtualを付けていないんだが、これであってる?
http://pc12.2ch.net/test/read.cgi/win/1237525619/127
442 :
440 :2009/04/05(日) 21:09:30
ごめん
別スレで無礼者がいたから
そいつへレスしようとしてたら
間違ってこっちにリンク張っちまった。
>>441 マジごめん。
virtualつけたメンバ関数は、派生クラスではvirtualをつけてようがつけてまいが関係なく 仮想関数になる DerivedもDerived_Derivedもvirtualはつけてもつけなくても一緒
>>443 ありがとう。
ちなみにどちらでも同じということだが、その場合
virtualは付ける方が良いとか付けない方が良いとかそういう慣習があったりする?
>>440 のコードを
Baseでvirtualを付けておき、DerivedとDerived_Derivedではvirtual付けない版と、
Baseでvirtualを付けておき、DerivedとDerived_Derivedでもvirtual付ける版と
両方を作ってビルドしてみた。
g++ -O2 ~~.cpp
としたのだが、挙動は一緒みたいだが、バイナリは違うものになった。
何故?
-Sで試して確かめるならまだしも…
>>446 -Sだったら同じバイナリになったわ。
なんで??
448 :
447 :2009/04/05(日) 22:25:58
>同じバイナリ →アセンブラコード
>>444 C++ Coding Standards では派生クラスでもつけたほうがよいと書いてある。
(38項.安全なオーバーライドを身につけよう)
単に利用者に意図を明確にするためだけどね。
速度限界まで最適化するときに virtualってどう扱うべきなのですかね?
@Override みたいなのが欲しいよね
そこで属性でしょきっと。
453 :
デフォルトの名無しさん :2009/04/06(月) 00:43:53
#define override virtualってうちの会社の元Delphi使いな先輩がやってた。
>423 遅レスだけど、削除を別のfriend classに委譲する時なんかで使う。 こんなの class A { private: ^A() {}; class deleter { void operator()(A* target) { delete target; }; } friend deleter; public: boost::shared_ptr<A> creator() { return boost::shared_ptr<A>(new A, deleter()); }; }
class Singleton { Singleton() {} ~Singleton() {} public: static Singleton& Instance() { static Singleton instance; return instance; } }; みたいなやり方がどっかに載って無かったかな。
456 :
423 :2009/04/06(月) 21:40:38
関係ないけど singletonをtempleteにするとctorはpublicにせざるをえないのかな? よくそういう実装をみかけるけど、新しいインスタンスを作れるのがイヤなのですが
ctorをprivateにしてsingletonをfriendにすればええがな
そもそもシングルトンをテンプレートにしてまで量産しようという考え自体が間違いだな。
CamelCaseにするかcamelCaseにするかcamel_case(underscore_style)にするか、 その基準とか主張とかメリットとかデメリットを知りたいんだが、 みんなどうしてる? 確かBoostは俺の知る限りunderscore_styleだったと思うのだが。
461 :
デフォルトの名無しさん :2009/04/07(火) 19:27:32
>>461 テンプレートにしているから量産しようとしているとespしたんじゃない?
マヌケなespだな
どうでもいいがespがスタックポインタに見えてしょうがない
ttp://d.hatena.ne.jp/portown/20090318/1237389062 ここで、
>「デストラクタがヘッダ中に記述されてしまっている」ことにある。
>更に言うと、「deleteがヘッダ中に行われてしまっている」ことが問題であり、
>よりつっこんで言うなら「deleteがCHoge::implの定義と別の場所で行われている」ことが問題なのだ。
>つまり、pimplにスマートポインタを使おうとするなら、デストラクタを必ず明示しなければならないのである。
>それも、implの定義(この場合はhoge.cpp)と同じ場所に、だ。
ってあるんだけど、その意味が分からない。
何でダメなの?
つーかコンパイルは一応通ったんだけど。
間抜けな設計に合わせてespのレベルも落としたんだろ
>>465 まず、「不完全型(名前だけ分かってるけど完全な定義がまだ見えていない型)のポインタのdeleteは危険」
であることを知ってほしい。これはコンパイルは通るけどきちんと動かないことがある。
(その型に自分で定義したデストラクタやoperator deleteがある場合、ちゃんと呼ばれない。)
class CHogeのデストラクタを記述しない場合、コンパイラが勝手に ~CHoge() を作る。
その中でスマートポインタである pimpl のデストラクタが呼ばれ、不完全型であるimplのポインタをdeleteしようとする。
未定義動作だからまともなコンパイラなら警告くらい出すはずだけどな たまたまデストラクタもdeleteも定義してなかったからスルーしちゃったのかな
>>467-468 ありがとう。
「pimplがスマートポインタであるために特殊なdeleteが必要である。
だがコンパイル時にはpimplが不完全型であるためにその特殊なdeleteを呼び出すコードが作られない。」
ってことか。
となると、今回のケースでは
CHoge::~CHoge(){}
を自分で明示的に記述したとしても、それをhoge.hに書いている限りは解消されないんだよね。
hoge.cppのCHoge::implクラスの定義の後に自分で明示的に記述するならOKってことですかい?
>>469 前半は違う。スマートポインタであることは本質的な問題ではない。
pimplが単なるポインタであっても、 hoge.h でCHogeの定義の中に
CHoge::~CHoge() { delete pimpl; }
と書いたら、全く同じ問題が生じる。
後半はあってる。とにかく、明示的にであれ暗黙的にであれdeleteが出てくるところでは、
そのdeleteされるものの完全な定義が分かっていなければまずい場合があるということ。
471 :
469 :2009/04/07(火) 22:25:09
>>470 なるほど。
根本的な問題は「デストラクタが云々」じゃなくて、
「不完全型のポインタのdelete」にあった訳か。
んで、その辺を全部気にせず丸投げしてもいけるのがshared_ptrなのか。
ありがとう。
・・・しかし
>
>>468 >未定義動作だからまともなコンパイラなら警告くらい出すはずだけどな
VC++2008で試して見たのだが
>auto_ptrを用いた例ではVC++2008では警告しか吐かれない。
なぜか警告すら出てこなかったなぁ。
472 :
471 :2009/04/07(火) 22:29:09
>>468 警告でた。
お騒がせしました。
warning C4150: 'CHoge::impl' 型を削除するため delete 演算子が呼び出されましたが、定義がありません。
: 'CHoge::impl' の宣言を確認してください。
473 :
471 :2009/04/07(火) 22:33:37
追記: g++でも警告出た。 note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined. bcc5.5.1では警告でなかった。
explicitをデフォルトコンストラクタに付ける意味はありますか? また、explicitを引数を2つ以上取るコンストラクタに付ける意味はありますか?
1.デフォルト引数が付いてて、結果的に引数1個で呼べるなら意味がある 2.付けても害はないのでとりあえずコンストラクタには全部付けるポリシーにして付け忘れを防ぐ
explicitを付けさせる仕様でなく、 implicitを付けさせる仕様にすべき
>>476 いまさら仕様変更されても困るから、そうなってたらいいな、って話にしかならん。
478 :
474 :2009/04/08(水) 07:09:56
copy-and-swapイディオムってすげーのな。 これって自作クラスのoperator=のオーバーロードの定義以外に使い道ある?
480 :
デフォルトの名無しさん :2009/04/08(水) 19:11:38
何がすごいの?
>>479 コピーしないでスワップするだけなら、
参照型の引数で値を戻す場合にも。
void foo(hoge_t& result)
{
hoge_t x;
//xにあれこれ手を加える
swap(x, result);
}
まあ、何も考えなくていいときには、resultを直接いじることもあるけど。
全部正常に終わるまで変更を反映させたくない処理全般に使えるよね。
484 :
479 :2009/04/08(水) 20:21:49
オーバーロードしたoperator=を コピーコンストラクタの定義で使っても大丈夫?
よゆー operatorほにゃららは普通の関数と全く同じように呼び出して可。
>>482 ドラゴン・スゴイコビッチ!(とてもすごいの意)
用件としては、自作クラスに swap 関数を装備することと、
その swap が例外を投げないようにすること?
488 :
485 :2009/04/08(水) 21:49:40
>>486 ありがとう。
コピーコンストラクタ(に限らずコンストラクタ一般)から
メンバ関数を呼び出す時、
construct中なのにメンバ関数を呼び出しても
大丈夫なのだろうかと思ったのだ。。。
>>488 virtualなら気をつけないといかんかもしれんが
そうじゃないなら大概大丈夫
大丈夫
>>489 >virtualなら気をつけないといかんかもしれんが
ああ、
基底クラスのconstruct中にvirtualなメンバ関数呼ぶと
その基底クラスでの対応するメンバ関数が呼ばれるってやつね。
ありがとう。
>>490 ありがとう。
C++0xは本当に後 数ヶ月で策定されるんだろうか。 されたとして、ちゃんと動作するコンパイラが出て来るのはいつだろうか。 ・・・うむ、心配だ。
別に心配することじゃない。 まともなコンパイラが出てから考えればいいこと。 早く出てくれないと困る事情でもあるのか?
すまぽとかは早く表順になってほしいなぁ。 もうすまぽを書くために何リットルのインクを消費したことやら。 (インク?)
495 :
492 :2009/04/08(水) 22:52:55
>>493 >早く出てくれないと困る事情
いや、全然ないw
g++が速いかVCが速いか。
>>493 IntelC++は既にlambda関数がサポートされてるんだけど、IntelC++はコンパイル遅いんでdebugはVCでreleaseはIntelでやってるとlambda関数は使えなくて残念。
boost::lambda使えば済む話ではあるんだけど。
497 :
492 :2009/04/08(水) 23:12:20
現在のTR1のライブラリ達は、正直なところ十分動作することが 確認されるまでは使わない方がいいんではないかと思うんだが。 それまではboostのが安心かなぁ。 でも標準に入ってる方が使うのは(気分的に)もっと楽になる事は確か。
class A{ public: virtual ~A() = 0; }; class B :public A {}; class C :public B { public: ~C(){}; }; gccでundefined reference to B::~B()って怒られるんだけど、Bでd-tor書かないとダメ?
ごめん。純粋仮想d-torに定義書くの忘れてた
俺としては以下のやり方でMyClassクラスによるstd::swap関数テンプレートの特殊化を行い、 using std::swap; swap(x,y); で特殊化したstd::swap<MyClass>が呼び出せるかと思ったのだが、 以下のやり方だとなにか定義がかぶっているようなことを言われてエラーになってしまう。 再現するソースは次のようなもの。 //以下はMyClass.h class MyClass { char *p; public: void swap(MyClass &hoge); MyClass(); ~MyClass(); }; //以下はMyClass.cpp #include <algorithm> #include "MyClass.h" MyClass::MyClass():p("pointer"){} MyClass::~MyClass(){} void MyClass::swap(MyClass &hoge) {std::swap(this->p, hoge.p);} namespace std { template<> void swap(MyClass &lhs,MyClass &rhs) {lhs.swap(rhs);} }
501 :
500 :2009/04/09(木) 00:18:28
//以下はmain.cpp #include <algorithm> #include "MyClass.h" int main() { MyClass x,y; using std::swap; swap(x,y); return 0; } としたら、g++にて MyClass.cpp:(.text+0x42): multiple definition of `void std::swap<MyClass>(MyClass&, MyClass&)' main.cpp:(.text$_ZSt4swapI7MyClassEvRT_S2_[void std::swap<MyClass>(MyClass&, MyClass&)]+0x0): first defined here collect2: ld returned 1 exit status というエラーが出る。 どうしたらいい??
理由は覚えてないけどstd名前空間の中でswapの特殊化しちゃだめだった気がする。 ちょっと俺も確認してくるか。
503 :
502 :2009/04/09(木) 00:33:03
別に駄目じゃないか。ごめんスルーしてくれ。
>>500 std::swapの特殊化はヘッダに書かないと駄目だろう。
main.cppでは特殊化したstd::swapが見えないから標準のstd::swapが実体化され
MyClass.cppで特殊化した物と衝突してるんだろう。
>>504 そうか。
コピーコンストラクタの定義に代入演算子を使うと定義が循環しちゃうのか。
507 :
500 :2009/04/09(木) 06:58:19
>>505 なるほど。
std::swapの特殊化をヘッダに書く場合はinline指定しないと、
そのヘッダをインクルードするたびにまたmultiple definitionってなっちゃうかな?
509 :
500 :2009/04/09(木) 08:22:57
>>508 (1)main.cppでは特殊化した定義がその前になされていないから通常通り実体化。
(2)MyClass.cppでも特殊化した。
この(1)と(2)でmultiple definitionってことか。
つーことで
MyClass.hにstd::swapの特殊化を書く(1)
main.cppでMyClass.hをインクルード
ってこと?
510 :
508 :2009/04/09(木) 08:24:06
>>507 あ、ヘッダに書かないといけないのは理解してるのか。ごめん
テンプレートの定義は inline じゃなくてもいいよ。 >500 の場合は inline が
適切だと思うけど。
これが inline じゃないといけないんなら全部の関数テンプレートが inline にならないといけなくなるな。
512 :
インドリ :2009/04/09(木) 10:05:14
しかもマルチかよ。何のつもりだ?
インドリしゃんに粘着する物好きもいるんですね
517 :
デフォルトの名無しさん :2009/04/09(木) 14:28:38
C++でGUIのプログラムを作ろうと思うんだが、お勧め開発環境はなにかないか?
また環境も書かんと適当に訊くなあ。
519 :
デフォルトの名無しさん :2009/04/09(木) 14:51:01
C++Builder(8万円くらいする) Turbo C++(C++ Builderの無料版 機能が削られていて少し古い) Qt Creater(マルチプラットフォームのソフトが作れる コンパイルが遅い)
521 :
デフォルトの名無しさん :2009/04/09(木) 15:08:24
>>520 turbo c++でGUIって開発できるの??
できるよ
523 :
500 :2009/04/09(木) 22:50:09
>>510-511 そういえば関数テンプレートの定義は
ヘッダに書くけど、それは普通の関数の類推で
inlineじゃなきゃいけないなんて考えちゃだめなんだったな。
Effective C++に書いてあったような気がしてきた。。。
ありがとうお二方。
std::powとかhypotとかをスレッドセーフに実行したいんだけど、おみゃーらどうしてる? 軽いに越したことはないずら
常識的に考えればスレッドセーフでないわけがない。 って書こうとしたが、errnoとか気にしている?
あれ?そうだったの?errnoは気にしてない。 うーん、じゃあ他のところで変な風になってたのかにゃ・・・? ありがとうござんした
529 :
デフォルトの名無しさん :2009/04/10(金) 08:30:05
errnoを気にするとどうなの?
>>529 errnoはグローバル変数なので、
errno = 0;
std::pow(x, y);
if (errno != 0) { /* 失敗 */ }
みたいなコードを書いたときに、powとifの間で他のスレッドによってerrnoが変更されてしまう可能性がある
だから、errnoを気にするとpowとかはスレッドセーフじゃなくなる
たいていのコンパイラにはerrnoをTLSに置いてスレッドセーフにするオプションとかがあるけどね
タクティカルレーザーシステム?
>>531 いやTrue Love Storyです。
じゃなくてThread Local Storageです。
元気でね 頑張ってね 手紙書くね たまに会えるよね なんでかな 寂しいのに 寂しいよと 言えなかった
wwwwwwwwwwww
イイハナシダナー
>>530 よく分からんがerrornoへの代入って規格的に許されてたっけ?
18歳以上ならeroero挿入おkだよ
はいはいエロスエロス
18歳以上なのに、いつになってもeroeroの値がインクリメントされず初期値のままです。
>>539 君の中ではその変数は1つだけ存在すれば十分だよね。
俺達他人に迷惑書けて欲しくないから、君の実装から外には出さないで欲しいなぁ。
ってことでeroeroは自動的に0に初期化されてます。
E2BIGになって困る
>>536 大丈夫です
C99(ISO/IEC 9899:1999)の7.5の脚注170に「むしろそうするべき」って書いてある(C++の規格には「Cの規格を見てね」って書いてある)
若干スレ違いな気がして申し訳ないんだが、 C++の書籍(他の言語は知らんけど)って正誤表無いor乏しいの多くない? 『Exceptional C++』を買ったんだけど、1ページ目から 誤植と思われる物があって困る。。。 だれか正誤表作ってくれている人とかコミュニティとか無い??
グローバルスコープに std::string foo(); って書いたら、 std::string型を返す、引数のない、fooという名前の関数の宣言になるの? それとも std::string型のfooという変数の宣言とデフォルトコンストラクタ呼び出しになるの?
一応書いとくけど、ローカルスコープでもクラススコープでも同じだから。 ローカルでも関数の宣言は出来るからね。
これもちなみに 強制的に変数の宣言とデフォルトコンストラクタと見なさせるには std::string (foo()); と書けばよかったような 間違ってたらすまん
やってみたけどあかんかった カッコつけても関数宣言と見なされる std::string foo(""); と何でもいいからパラメータ付けるしかないな
んばば んばんば えらったえらった
553 :
544 :2009/04/11(土) 23:51:04
>>551 いや、日本語でググったりピアソンエデュケーション社の
Webページで検索してみたりしたんだが英語は見落としていた。
ありがとう、恩に着る。
554 :
545 :2009/04/11(土) 23:55:38
>>548 ローカルでは関数の宣言だけは出来るけど定義はできないんだよね。
ありがとう。
>>555 じゃなくてstd::stringのコンストラクタ呼び出したいんだけど
>>556 だから括弧つけなければいいなじゃないの?
std::string foo;
これでデフォルトコンストラクタ呼び出しになるでしょ?
デフォルトコンストラクタの話じゃなかったのか。 デフォルトじゃないなら引き数書くのは当たり前だろ。
なんだ? 未来指向なプログラムの話か?
560 :
まとめ :2009/04/12(日) 00:53:22
要は 1. std::string str="hogehoge"; ならstrの宣言&"hogehoge"を引数にとるコンストラクタの呼び出しとなる。 2. std::string str("hogehoge"); って書いてもstrの宣言&"hogehoge"を引数にとるコンストラクタの呼び出しとなる。 3. std::string str(const char* arg); ならstd::string型を返し、const char*を引数にとる関数strの宣言となる。 これを引数なしverにすると 1'. std::string str; ならstrの宣言&デフォルトコンストラクタの呼び出しとなる。 2'&3'. std::string str(); ならstd::string型を返し、引数のない関数strの宣言となる。 ってことだよね。 たぶんこのスレのみんなは分かっているけどレスが言葉足らずでカオスになっているだけかと。
>>556 もし、本当に「デフォルトコンストラクタを呼び出したいだけ(変数は用意したくない)」なら
std::string();
と書けば呼べるだろうね。
もちろん、ソース上には現れない一時変数が用意されるだけだけど。
普通に「デフォルトコンストラクタで初期化される変数を用意したい」ならば
皆が書いているように
std::string str;
とすれば良いだけ。
純粋なC++で、初心者でもないのにgotoを使う人って見たことある? やるとしたらスパゲッティにならないで使える人なんだろうけど。
goto使えば二重三重ループから一気に抜けられるじぇ
あなた天才
565 :
562 :2009/04/12(日) 16:26:45
まあネストしたループから一気に抜けるって使い方か。 別の方法としてわざと例外をthrowしてるヤツがいたけど それよりはマシか。 変なフラグ変数用意するくらいならgotoのがいいのだろうか?
フラグ変数なんか使うな プログラムの見通しが悪くなる
567 :
562 :2009/04/12(日) 16:31:09
>>566 ですよねー。
俺もそう思うよ。
サンプルソースならともかく
flagとかhogeっていうフラグ変数を
用意しているヤツを見ると
もう頭痛がしてくる。
クラス設計で、メンバ関数はどの順番で記述する? 例えば基底クラスでpolymorphicな使い方を想定しているとして。 以下public指定なものだけを書く。 class ~~{ 1.コンストラクタをずらずらと。 2.virtual デストラクタ。 3.swap()メンバ関数 4.これら以外の普通のdo_something()メンバ関数をずらずらと。 5.operator= 6.operator+ 7.以下必要ならoperator云々 }; ってな感じにすれば良い? 今ひとつ経験不足でどんな感じが良いのかわからんのだ。
569 :
568 :2009/04/12(日) 16:36:50
>基底クラスでpolymorphicな使い方 ってまあ要するに基底クラスのポインタに派生クラスのポインタを変換して使うつもりって言いたい。
まぁ、多重ループから一撃で抜けるなら その部分をカプソー化してれつるんで抜ける方が スマートな気もするよね。
572 :
571 :2009/04/12(日) 16:39:47
>>566 下手するとgotoなんかよりずっとスパゲッティーになるな
フラグ変数が2つ出てきたり、状態が3つとかあったりすると死ねる
>>573 やっぱ2重程度ならともかくそれ以上多重にネストしているあたりから
おかしくなり始めていると考えた方が良いのかなぁ。
フラグって一切使っちゃダメなん? 一切使うな的なことを初めのころ本で呼んで、 それ以来、可能な限り使わない方法を考えてる。 フラグを使わない方法を考えるだけで1日潰すなんてザラ。 でも、実際仕事を始めたら、普通にみんな使ってるし、 大体、DB自体がフラグのカラムでいっぱいだし、 そうなるとコード側でもフラグを操作しないとダメになる。 何が言いたいかっつーと、 フラグを使いまくってる職場のプログラム設計がおかしいのか、 フラグ排除主義の過激派が悪いのか、真理を教えてくれ
別に、そう深刻に考える問題でもないと思うけど。
>>567 は逆に考えれば、明快な名前を持つフラグ変数ならマシってことでもある。
フラグや多重ループはベタなコードを一度書いてみてジックリ考察すれば 単純なクラス構造に落とせると思うっス 使い捨てクラスが増殖するけど 後の状態変数の把握のし易さは別次元。
まぁ、アジャイル・プラクティスの教えに従えば、何事もバランスが大事。 そして、ダメだとわかったときにはリファクタリングする勇気。 でも、できればフラグやgotoは減らしていきたい。
gotoなんか使ってる奴はダメだね
男ならsetjmp/longjmpだろ
と行きたいところだがある意味
>>565 で既出だった
恩師、goto熊男先生いわく、 「ノォ!」 なので、gotoは使っちゃいけないと思うな。 (おっさん限定ネタ)
BreakTwoLevelsException
いや、最初の論点は 「goto使用を避けるためにフラグを使う」というのが最悪、ってことだろ。 もちろんフラグなんて可能な限り使わないほうが良いが、避けられないケースはある。 また、よく言われるループ内のswitchからの脱出の話題で 「switch使うな、classにしろ」という論も 猫も杓子もそうしろと言い出すのはナンセンスとしか言い様が無い。 「return使え」も同様。 要は、臨機応変に適材適所で手元にある道具を使え、ってことだ。
内部ループ部分の関数括りだしや、contiue を活用すれば、二重以上のループは 殆ど登場しないから、個人的には goto は要らないな。 STL やファンクタも併用すれば、ループそのものの登場機会が減るし。
このスレって荒れないね。 すばらしい。 理性的な人がそろっているな。
C++は、使う人が理性的でないと、大変なことになるからかもね
でも、スコットメイヤーもハーブサッターも 著書の中で毒舌はきまくりだよ。
>>581 BreakがTwoLevelsかどうかはcatch節によるんで、その名前はあんまりです。
C++で正常系なのに例外を使うなんて信じられないっす
局地的な使い捨てフラグの禁止は古い最適化思想の名残のような感じがするけどなぁ。 大局的にはフラグ専用の変数を用意してあちこちで状態を変更しまくってると ・フラグの状態を変更すべき処理を追加・変更したのにフラグの変更処理を忘れる ・フラグの今の状態がどこで変更された結果なのかがわからなくて状態の信頼性に欠ける とかの問題がでやすくなるから気をつけろってことだろ。
みんなそういう意味で言ってたと思うよ。
ユーザ定義リテラル使って、 throw "hoge_loop"_break; とか。
ある自作関数が1行で終わるとても短いstatic関数だったので、 それを実装ごと丸々ヘッダhoge.hに書きました。 特にinline指定はしなかったのですが、 そのhoge.hをインクルードするソースファイル.cppが複数あるにもかかわらず g++で問題無くコンパイル・リンク・実行できました。 普通の関数だったらmultiple definitionとか言われるはずだと思うのですが、 static関数なら大丈夫だったりするのでしょうか?
はい。ただし無駄です。
>>584 そう言われると、なんだか最近まったり進行している気がしてくる。
>>592 (メンバ関数でない)static関数とはまさにそういうものだろ。
>>586 毒舌っていうのは理性と知性によって導き出されるものだよ。
馬鹿な人間が感情のままに吐くのは、面白味も攻撃力も無い単なる罵倒。
ごめん、何に噛み付いてるのかよくわからない。 メイヤーズやサッターが理性的でないと言いたいのか、 それとも「毒舌というのが知性や理性の欠如から出るものなんだ」と主張したいのか、 それとも普段の自分が否定されたみたいで悔しいのか。
ごめん、何を必死に弁解してるかわからない。 いや、マジで
>>599 かみつくという認識もないくらい、ただの脊髄反射煽りだから気にすんな。
>>601 そうやって煽り返すから荒れるんだよ
もう少し自重しようよ
>599はどのレスの人間で、どのレスに噛み付かれたのかと思ったんだ?
604 :
デフォルトの名無しさん :2009/04/13(月) 17:21:35
メイヤーズやサッターが知性も理性の欠片もない。 面白味も攻撃力も無い単なる罵倒。
わどらー
プログラム中でint型の変数を2種類(a,bとする)定義し、その2つによって複 素数の型の要素を持つa列b行の2次元配列を定義したいのですが、 ------ #include <iostream> #include <complex> using namespace std; void main(){ int a,b; complex<double> c[][]; cin >> a; cin >> b; complex<double> *c = new int[a][b]; ------ これでエラーが多発してしまいます。 配列の定義に問題があれば教えていただけないでしょうか。
std::vector<std::vector<std::complex<double> > > c(a, std::vector<std::complex<double> >(d));
>complex<double> *c = new int[a][b];
型が違うからね。
>>607 の方法が一番素直なやり方と思う。
×(d) ○(b)
std::vectorならresize()メソッドが使えるから後から大きさを変更する事もできる アクセスは c[1][2] のように書ける
Boostを使ってもいいなら、boost::multi_arrayを検討してみるのもいい。
612 :
デフォルトの名無しさん :2009/04/13(月) 22:26:09
file 1 template<class T> class Parent { void Umu() { Child* p = new Child; p->Method() } }; file 2 template< class T > class Child { void Umaseru() { m_pParent->Umu(); } } テンプレの場合、実装部分をcppに退避する事ができないので、 上記のような相互参照するクラスのテンプレートって実装できないのでしょうか?
先行宣言すればいいよ
先行宣言しても、そのクラスのメンバ呼出ししてたらコンパイルできない気がする。
基底クラス内にあるクラスは派生クラスで特殊化可能ですか?
a Gr bner basis
template<class T> class Parent { void Umu(); }; template< class T > class Child { void Umaseru() { m_pParent->Umu(); } } template<class T> void Parent::Umu() { Child<T>* p = new Child<T>; p->Method() }
質問です。お時間あればよろしくお願いします。 -------------------------------- class Base { // 省略 virtual size_t getSize() const { return sizeof(*this); } }; class Derived : public Base { // 省略 }; int main() { Derived d; d.getSize(); -------------------------------- d.getSize()の値がBaseなのですが、自分が期待していたのはDerivedのサイズの取得です。 DerivedではgetSize()を定義せず、 Derivedのサイズを返すメンバ関数をBaseで定義することはできるでしょうか? 何か良い方法があれば教えていただきたいです。
>>618 もし、Derivedにprivateなメンバ関数を追加することが許されるのであれば、
BaseとDerivedに、それぞれsizeof(Base)とsizeof(Derived)を返すprivateでvirtualなメンバ関数を追加する。
で、Base::getSize() からはそれを呼び出すようにする。
原則としてsizeofの値はコンパイル時に決まるのであり、実行時の型で決まるものではないことに注意。
(C99の可変長配列は例外となる。)
>>619 早速の返答ありがとうございます。
なるほどサイズは動的に決まるわけではないんですね。
そもそもこんな事をしたくなる設計がよくないんでしょうかね…
ifstreamでバイナリファイルを読み込んでいます。 現在の読み込み位置のアドレスを知る方法はないのでしょうか? operator>>で読み込むたびにカウントするしかないのでしょうか?
ファイルサイズはseek+tellで得るのが定石だった頃が俺にもありました
>>620 もしよければ、なんでサイズを取得する必要があるのかを教えてくれないか。
今までそういう場面に遭遇したことがない。
インスタンスの正体を調べたいなら、getClassのインプリメントなりdynamic_caseで済むと思うが・・・
625 :
592 :2009/04/16(木) 13:48:03
>>593 >>595 ありがとうございます。
どうやら私のstatic関数への理解がおかしいみたいなので、
勉強してきます。
なんか同じstaticという予約語を使っていながら、
使い方しだいでだいぶ意味が違う気がするんですが・・・。
>>625 > なんか同じstaticという予約語を使っていながら、
> 使い方しだいでだいぶ意味が違う気がするんですが・・・。
いかにもそのとおり。
それが嫌なので、C++ではグローバルでstaticなものを宣言する代わりに、無名名前空間が推奨されている。
627 :
621 :2009/04/16(木) 19:05:12
>>622 ありがとうございます
おかげさまで tellg, tellp, seekp, seekg 等を知ることができ
無事プログラムを動かすことができました
C++のifstreamではtellp==tellg、seekp==seekgなんだよな stringstreramではtellp!=tellg、seekp!=seekgなのに この事に気づくのに手間取ってしまった
ifstreamにtellp、seekpは無いっしょ
>>629 ある
普通に使える
が、tellpはtellgと同じ意味になるし、seekpはseekgと同じ意味になる
やってみそ
たしかfstreamでもpとgのシーク位置は連動するはず。
632 :
629 :2009/04/16(木) 22:53:10
>>630 fstreamにはpとg両方あるけど、ifstreamにはgしかなくね?
>>632 悪い
fstreamでなくてifstreamだったか
酔ってるスマソ
Windows XPのコマンドプロンプト画面から g++ hoge.cpp piyo.cpp みたいな感じで使えて、 標準準拠性も良くて、無料な コンパイラ(リンカ付き)ってありませんか? g++を使っていて、エラーメッセージがイミフな時に別のコンパイラで試すのに使いたいんです。 VC++だとコマンドから使えないですよね?
つかえますよ。
>>635 まぢすか。
VC++が使えれば文句ありません。
もう一度調べ直してきます。
windowsで無料で使えて新しめってg++とcl位?
ちょっとスレ違いになってしまうかもしれないんですが、 巷で言われているメモリプール化というのをしようとしてるんですけど 概念として教えてもらいたいものがあります。 ヒープ領域とは全体の確保されたメモリ チャンク領域とはこれから使う為にヒープ領域から必要なだけ小出しに取ってきたメモリ って感じでいいんでしょうか? プールとは?チャンクと同じような概念でよろしいでしょうか?
ヒープ領域 newでシステムから借りてきたメモリ領域。 プール=確保したもの、プール金とかのプールと意味は同じ。予めシステムから借りておく。 お金が必要なたびにいちいちATMに逝くのではなく、必要になる前に家に現金を置いておくイメージ。 チャンク=こまぎれ。 数バイト毎とかでチマチマ確保すると効率が悪いので、大きな単位で確保する。 必要な額だけをATMからおろすのではなく、必要な額を10万円単位で切り上げておろす、みたいなイメージ。 1万円必要になったら10万円おろし、 11万必要になったら20万円おろす。
その手の比喩は、7-8割理解できている人間に「トドメの刺す」のには有効だけど、 初期に読まされると余計混乱すると思うよ。
×トドメの ○トドメを
>>638 「Effective C++」に確か、実例つきで説明があったはずだから、
それを読んでみるといいんじゃないかな。
~_tはtypedefの証というけど、 これは規約上予約されている? 例えば自分で numeric_t とかしちゃだめ?
全然。いくら使っても大丈夫。_tamuraとか__tamuraとかも衝突しない限り使って大丈夫。
>>643 ありがとう。
MY__M__A__C__R__O
とか予約されてるじゃん。これと同じ感じで予約されてたらやだなと思ったのだ。
> MY__M__A__C__R__O なんだ俺の知らない世界の話か Cのプリプロに名前を教え込むのは極力避けたい
>>643 _tamura はグローバルでは予約されてるから使えない。
__tamura はどこでも予約されてるから使えない。
// main.cxx namespace { typedef int _INT; } int main() {} std::でもグローバルでもないならおk?
>>647 _INT みたいにアンダースコア~英大文字で始まる名前は
ダブルアンダースコアを含む名前と同じくどこでも予約。ダメ。
>>645 _が二連続した名前は予約済みなんだよ。
s/_INT/_iNT/ # おk?
どこの独自コンパイラだよ^^ _hoge も __fuga もうちのコンパイラは全然大丈夫だよ。
>>647 ,650
アンダースコア~英小文字で始まる名前はグローバルで予約されてる。
処理系がグローバルに _iNT って名前を置いてたら曖昧になっちゃうから、
すぐに未定義動作とは言えなくてもやっぱりダメだろう。
早い話、そもそもアンダースコア始まりの名前なんか使わなきゃいい。
>>652 予約されてるかどうかが問題なんだよ。
今大丈夫でも、コンパイラを変えたりコンパイラのバージョンやコンパイルオプションを
変えたりしただけでエラーになるコードじゃ困るだろう。
>>653 すべての識別子において、
ファイルスコープを持つ ならば グローバルスコープを持つ
ということ??
656 :
655 :2009/04/17(金) 13:24:20
自己解決しました
658 :
デフォルトの名無しさん :2009/04/17(金) 22:21:47
演算子について教えてください。 (見やすさとか保守性とかは考えないとしてC++の規格上) a と b が int 型の時、 以下の表現は問題無いでしょうか? 『 b ? a=b : a++; 』 ? : よりも = の方が優先順位は低いのですが、 ? と : は2個セットの演算子なので、 (b ? a) = (b : a++); このように別々になることができず b ? (a=b) : a++; の解釈しか出来ないはずで、 VCでも正常にコンパイル出来、ちゃんと動作します。
>>658 うん、大丈夫。
文法上、「論理和式 ? 式 : 代入式」となっているので問題ない。
そう、ついでに言えば、?と:の間に?:を入れ子にもできてしまうということも導かれる。
661 :
デフォルトの名無しさん :2009/04/17(金) 23:54:12
暗黙の型変換について教えてください。 以下のようなものはdoubleからintへの暗黙の型変換は行われないのでしょうか? 私の環境ではコンパイルエラーになってしまいます。 int a[1.0]; int b = 1%1.0; int c = 1&1.0; enum{d=1.0}; 暗黙の型変換が行われない例は他にありますでしょうか?
doubleの値はintでは表現できないので暗黙に変換できない。 基本的に情報落ちが発生する方へは暗黙で変換できない。
処理系によるぞ VC9だと、 int i = 1 * 0.8; は warning 扱いになる。(int)で黙る。
型変換にはいろいろあるんだぞー 算術式での格上げとか暗黙の型変換とか
665 :
おもち :2009/04/18(土) 00:39:16
プログラム初心者なのですが、いい参考書などないでしょうか?
667 :
デフォルトの名無しさん :2009/04/18(土) 00:44:18
>>666 久しぶりに激しくワラタwwwwwwwwwwww
・・・俺も寂しいな
>>665 感覚を養うために難しい本じゃなくまず
センスオブプログラミングみたいな素養本を読め
言語本は辞典代わりで十分
初心者がC++・・・うーむ。 大概の入門書はCを知っていることを前提に書かれているからなぁ。 ところで、大昔javaが出たての頃に読んだ入門書は C++を知っていること前提みたいな内容だった。 どこでもかしこでもC++との比較が載っていて、 そんなのが全体の1/4くらいを占めていた。 何も知らないで使えるのはBASICとかRubyとかそのへんかな。
コンピュータのことを知らなくてもできるのはhaskellかな… 別の知識がいるけど、基本は因数分解と展開(四則演算より単純な算術)なんで 人によっては普通の言語よりわかりやすいのかもしれない ついでにC++は普通の言語と関数型言語の難しいところだけを集めたような言語だと思ってる
ぶっとんでるな
>>662 >>663 >>664 関数の引数やコンストラクタはdoubleからintに暗黙的型変換が行われますよね?
int f(int a){ return 0 };
f(1.0);
int a = 1.0;
とかは大丈夫なはず。
これが大丈夫で、
>>661 がダメだというのは、
規格書のどの辺に書かれているのですか?
もしわかれば教えていただけないでしょうか。
自分で探せやカス
>>661 > int b = 1%1.0;
がdoubleに余剰演算かけようとしてエラーになってるんじゃないの?
式の中での暗黙の型変換なんだから1の方がdoubleに変換されて
> int b = 1.0%1.0;
になると思うんだが。
>>671 それは代入時の暗黙の型変換なんだから左辺側に変換される。
>>673 たとえば関数なら、
int a(int x,int y);
int a(double x,double y);
int b(int x,int y);
が定義されてたら、
a(1,1.0) は汎整数昇格の方が優先される為、
a(1.0,1.0) となりますが、
b(1,1.0) は b(1.0,1.0) の定義がないので
b(1,1) と変換されると思います。
%演算子の場合も同じように、1.0%1.0の定義が無いため
同じように1%1と型変換されたりしないのでしょうか?
あと、
int a[1.0];
enum{d=1.0};
これはNGですか?
>674 > 5.6/2 >The operands of * and / shall have arithmetic or enumeration type; >the operands of % shall have integral or enumeration type. The usual >arithmetic conversions are performed on the operands and determine >the type of the result. usual arithmetic conversion は 5/9 で規定されていて幅が広がる方向の 変換しか規定されていない。 >664 や >673 の言っている通り、どういう時にどういう変換がかかるかは一つじゃない。
> あと、 > int a[1.0]; > enum{d=1.0}; > これはNGですか? integral constant expression ではないので NG。 論拠は7.2/1、8.3.4/1、5.19/1。
7.2/1、8.3.4/1、5.19/1って何を見ればいいの? ネット上で閲覧できるもの?
ANSI規格。
で、それはネット上で閲覧できるもの? URLは?
ドラフトならタダで見れるだろ
で、URLは?
自分でググれよ
683 :
デフォルトの名無しさん :2009/04/18(土) 11:45:03
出た、「ググれよ」ww
そりゃ出るだろう。出る箇所だもの。
>>675 >>676 ありがとうございました。
書かれている場所まで記述していただいて
非常に参考になりました。
C++のANSI規格が見られるURLを教えてください。
一次ソースはISOな。 日本語訳がJISのサイトで閲覧できる。
で、URLは?
自分でググれよ
692 :
デフォルトの名無しさん :2009/04/18(土) 13:26:45
出た、「ググれよ」ww
そりゃ出るだろう。出る箇所だもの。
696 :
デフォルトの名無しさん :2009/04/18(土) 13:35:31
精神レベルの低い、幼稚なお子ちゃまがよぉ、軽々しく死ねとか言うなよ? お前を育てた奴は人間社会では、かなりレベルの低いバカだったんだな。 育てられたお前がかわいそうとか思わない。大人になって苦労するのはてめぇ。 いつか死ぬから、バカな存在として一生を無駄に過ごしなさい。
697 :
デフォルトの名無しさん :2009/04/18(土) 13:37:02
誤爆
軽々しくググれとか言うなよ
こんなものは最初からテンプレに入れとけって話だよ。 お前らの怠慢を質問者になすりつけるな。
どうかググってくださいお願いします。
701 :
デフォルトの名無しさん :2009/04/18(土) 13:44:37
人にググれという前に、自分でググって見つけたURLを貼りなさい。
で、何のURLを貼って欲しいの?
C++のANSI規格が見られるURL
とあるライブラリを使おうと思ったら、コールバック関数がCの関数ポインタでした。 データも渡したいんですが、関数オブジェクトが使えないので困っています。 データをグローバル変数にするしか方法はないのでしょうか?
とりあえず、使いたいライブラリの機能と、コールバック関数と、渡したいデータを教えてください。
そういうコールバックは、データを保持できるvoid *をペアで登録することができて そいつが引数としてコールバックに渡される仕様になってるはずだが そうでないならあきらめな
>>706 ちゃんとした物とちゃんとしてない物は何が違うの?
>>708 ちゃんとしていない物=非合法なコピー品。
提供した者の手が後ろに回る可能性がある。
あと、JISの規格書なんかは閲覧は出来てもダウンロードしてオフラインで見ることは出来ない。
>>709 ちゃんとしていない物=非合法なコピー品が何故公式ページからリンクされてるの?
まずはどこからどこへリンクされているのかURLを示せよ。 ISOのストアで販売しているものをISOが別のページでタダで配るわけないだろ。
713 :
711 :2009/04/18(土) 14:37:45
>>715 あ、公式っていうのはISOではなくJISのこと?
それはタダで見られる数少ない合法的なものだよ。
(ちなみにそのURLは検索結果のものだから他の人には見えないよ)
>>709 の文章の書き方が悪いって言う話?
ちゃんとしていないものの例=非合法なコピー品
と書くべきだったかな?
おまえら釣られまくりだな。
>>716 >>708 が言ってるのは、
>タダで見られる数少ない合法的なもの
と
>金を払わなければ見られないもの
の違いを教えて、ってことだと思うよ。
>※最新バージョン9の使用は今しばらくお待ちください。 おい。
久々に見に来たら何唾壺の有様は。 まったり進行していた時代はどこへ行った! 大人は黙ってまとめてあぼんだな。
セキュリティが厳しくなる前に保存しておいて正解だったな
static const volatile int x=42; とかあったとするじゃん。 この前のC++における型名や修飾子の順番ってどう規定されている? どんな順番が望ましいとか、どこまで好き勝手並べて良いとか。。。
この前っていつのことだよ。覚えてねーよ。
>>724 日本語おかしかったか。
static const volatile int x=42;
とかあったとするじゃん。
このように変数名の前につけるような
型名や修飾子の順番ってC++においてどう規定されている?
どんな順番が望ましいとか、どこまで好き勝手並べて良いとか。。。
const volatileって意味あるの?
>>725 別に決まりはないけど、まあみんな常識で考えて
記憶クラス指定子→cv修飾→型名の順番にしているね。
コンパイラを通すだけならint const volatile staticなんて並べても通る。
好みが現れるのはポインタ・参照の*と&の前後の空白の開け方、constとの順序だな。 int *p; int* q;とか。 const int* p2; int const* q2; 上のq2は、constなポインタへのconstで一貫性があるように見える。 const int* const p3; int const* const q3;
>>725 ストレージクラス(static) 型(int) cv修飾(const volatile) 識別子(x)
基本的にcvはその直前(左)にある型を修飾するけど、例外的にその左に型がない場合は直後の型を修飾する
規格では7.1あたりに書いてあるよ
一応誤解されないように言っとくと一番左の型の修飾子はその左に置くのが一般的だと思う static const volatile int x でok
732 :
725 :2009/04/18(土) 18:13:17
733 :
デフォルトの名無しさん :2009/04/18(土) 18:40:53
質問です struct fruit{ int apple; int banana; void clear(){ ZeroMemory(this, sizeof(*this)); } int orange; }; この構造体をローカル変数に定義した場合、メモリ見るとそれぞれの 3つの値がスタックに順に並びました。 clear を呼ぶと、確かに apple, banana, orange が クリアされます。 ZeroMemory で this を渡していますが、clear() は含まれていないようです。 この構造体の場合、fruit.clear() は main() と同じように、 code セグメントに配置されるんでしょうか。 class も同じ考え方になるのでしょうか。
>>733 当然、そうしないといけないという決まりはないが、
自然に実装すればだいたいそんな感じになる。classでも同じ。
735 :
デフォルトの名無しさん :2009/04/18(土) 19:49:59
>>731 コンパイラーによっては前付きは古いって怒られることあるよ。
ここらへんに増築の限界感を感じる・・・
1) const int *p; 2) int const *p; 3) int *const p; 1と2がpointer to const intで、3はconst pointer to intであってますよね?
738 :
デフォルトの名無しさん :2009/04/18(土) 21:57:16
あってます。
declarator としての const は常に * const の形で現れる。 っていうか、構文解析法は頭に叩き込みましょう^^
派生クラスのメンバ関数foo()が例えprivateでも、 基底クラスで同じメンバ関数foo()がvirtualと指定されていれば 基底クラスのポインタを介した場合のみ呼び出せるのか。 実際やってみるとうまくいくんだが、別におかしくはないよね? class Base { public: virtual void foo(){std::cout << "Base foo!" << std::endl;}; Base(){std::cout << "Base Constructor!" << std::endl;}; virtual ~Base(){std::cout << "Base Destructor!" << std::endl;}; }; class Derived : public Base { void foo(){std::cout << "Derived foo!" << std::endl;}; public: Derived(){std::cout << "Derived Constructor!" << std::endl;}; virtual ~Derived(){std::cout << "Derived Destructor!" << std::endl;}; }; void foo() { Base* pbd(new Derived); pbd->foo(); delete pbd; }
741 :
デフォルトの名無しさん :2009/04/18(土) 22:07:06
>基底クラスのポインタを介した場合のみ呼び出せるのか。 派生クラス(Derived)のポインタを介した場合でも呼び出せるでしょ?
おかしくないよ。 もし呼び出せなくなったりするのなら ポリシークラスとか存在価値なくなっちゃうし。
744 :
デフォルトの名無しさん :2009/04/18(土) 22:09:53
自分のメンバ関数なのに?
privateにしたら呼び出せなくなるのは当たり前だろ
746 :
740 :2009/04/18(土) 22:11:19
>>741 error: `virtual void Derived::foo()' is private
って言われますね。
>>744 「自分のメンバ関数から」ならprivateメンバ関数も呼出せるけどね。
747 :
740 :2009/04/18(土) 22:19:08
あと、基底クラスのデストラクタがprotected指定されていても、 派生クラスのデストラクタがpublic指定されていれば boost::shared_ptrを使った場合なら呼出せるのね。 必要条件: 基底クラスのデストラクタがprivateでないこと。 また、派生クラスのデストラクタがpublicであること。 さらに生のポインタじゃダメなようだ。
748 :
740 :2009/04/18(土) 22:20:08
class Base { protected: virtual ~Base(){std::cout << "Base Destructor!" << std::endl;}; public: virtual void foo(){std::cout << "Base foo!" << std::endl;}; Base(){std::cout << "Base Constructor!" << std::endl;}; }; class Derived : public Base { virtual void foo(){std::cout << "Derived foo!" << std::endl;}; public: Derived(){std::cout << "Derived Constructor!" << std::endl;}; virtual ~Derived(){std::cout << "Derived Destructor!" << std::endl;}; }; void foo() { boost::shared_ptr<Base> pbd(new Derived); pbd->foo(); } しかもboost::shared_ptrの動的削除子のおかげでデストラクタにvirtualすら付けなくてもいけるのか。
>748 >454
>>727 >ハードウェアが書き込み,プロセッサが読み出す領域: const volatile
この使い方って本当に大丈夫?
例示できないけどconst有り無しのオーバーロード関数とか・・・
>プロセッサが書き込み,ハードウェアが読み出す領域: volatile これも疑問だよな プロセッサもハードウェアも読み書きする領域じゃないのか?
752 :
デフォルトの名無しさん :2009/04/19(日) 12:16:38
そのコードが動作するプロセッサの管理外で読み書きされる領域
プロセッサによって細かい挙動は違うだろうけど、 volatileって常に最新の実体を参照するようにするだけだよね?
最適化を無効にしてるだけだから
その変数を扱っているプログラムとは別のなにかによって内容が変更されうる変数。 volatile int i; int j; if ( i == 1 ) j = i; で j == 1 でないときがありえる変数。 constをつけるとそのプログラムからは内容が変更できないのに参照するたびに内容はかわるかもしれない変数になる。 ポインタ経由でアドレスにマッピングされたI/Oポートとやり取りするのに使ったりする。
756 :
733 :2009/04/19(日) 14:51:18
>>734 thx! 亀レススマソ
「自然に実装すれば」というのは、アセンブル段階で
構造体やクラスのコードはすべて code セグメントに集約している
場合、ということでしょうか。
もう1つ謎なのは、インスタンス化を可能とするために、
clear() を呼んだ際に、どのメモリ領域が this に該当するのかを
どうにかして渡しているはずですが、その文献が見当たりません。
どのように処理しているんでしょうか。
>>756 > 「自然に実装すれば」というのは、アセンブル段階で
> 構造体やクラスのコードはすべて code セグメントに集約している
> 場合、ということでしょうか。
クラス(あるいは構造体)のメンバ変数は、
インスタンス毎に値が違うので、各インスタンスごとに
用意してやる必要があるが、メンバ関数は各クラス毎に
一つだけ用意してやればよい。
よって、
>>733 の場合だと、スタックにメンバ関数(へのポインタ)が
用意される必要はない(virtual関数は微妙に別)
> もう1つ謎なのは、インスタンス化を可能とするために、
> clear() を呼んだ際に、どのメモリ領域が this に該当するのかを
> どうにかして渡しているはずですが、
>>733 の例のclear()の場合、処理系が勝手に
__struct_fruit_clear(fruit* this)
のような関数に置き換える(ことが多い)。ただし、処理系依存。
758 :
733 :2009/04/19(日) 17:46:48
>>757 丁寧な説明、本当にありがとうございます。
かなり理解できました。
個人開発にて C++ にインターフェースの概念を取り入れようとしております。 .NET や Java では interface が言語仕様として存在しますが、 C++ では言語仕様レベルで Java のような interface は存在しません。 なので、単一継承とは別に、 純粋仮想関数だけで固められたクラスのみ、多重継承を許可して実装しようと思ってます。 そのような実装で問題点などありますでしょうか。 よろしくお願いします。
特に問題はないと思うけど、インターフェイスだと分かるようなクラス名にするとか工夫した方がいいかも 結局は規約次第だと思うが
>>760 レスありがとうございます。
やっぱり規約や、実装者の意識の問題になりそうですよね。
個人(自分だけ)での開発なので、その辺の問題は薄そうですが・・・
コンパイラで上手くカスタマイズして、
間違った実装したときに警告とか出せればいいんですけどね。
>>759 struct IHoge {virtual ~IHoge();};
struct IFoo : IHoge {};
struct IBar : IHoge {};
class Piyo : IFoo, IBar {};
Piyo piyo;
このとき、(IHoge*)(IFoo*)&piyo == (IHoge*)(IBar*)&piyoが
真になるとは限らないということを許容できないなら、仮想継承を使うべきと言っておく。
処理系間や多言語間での互換性を高めるため、仮想継承を使っていないMSのCOMでは、
これが理由でポインタの比較が面倒(仮想継承の代わりに規約で縛りを入れて対処している)。
>>762 operatorの再定義のことを言ってる?
よく分からん。
>>763 仮想継承しなければ、IFooの部分オブジェクトのIHogeとIBarの部分オブジェクトのIHogeは別物ということ。
インタフェースという元のお題からは外れるが、IHogeに非静的メンバ変数xがあれば、
IFoo側のxとIBar側のxは、仮想継承しないなら別々、仮想継承したら同一の存在だろ。
(かなり乱暴な言い方だけど)
それと同じ話。単にメンバ変数がないからポインタの比較でもしないと問題が発覚しないだけで。
教科書に書いてある内容なんだから 「仮想継承」も調べておいた方がいいとかで済ませればいいのに
>>762 レスありがとうございます。
仮想継承はよく理解してなかったんで、Wikipedia とかで調べてました。
多重継承する上で理解しておかないといけない概念ですね。
ありがとうございました。
おまえらスレがもったいないから
>>765 さんが教科書で覚えたことはいちいち説明するなよ。
ググレカス。
俺もC|Java|C#|VB厨だから仮想継承を調べてみた たしかにこれはググればわかる気がする 今後は namespace C++{ 仮想継承 } とか名前空間で囲んでくれると名前的にわかりやすい RDFでも可
namespaceは神 これさえあればC言語風に書けるしなw クラス? そんなもんいらね。
namespaceはCに取り込まれるべきだと思うね コメントの//より優先されるべきだった
namespaceだとC++と同じだから、namekukanでCに取り込んだら どうだろうか
772 :
デフォルトの名無しさん :2009/04/20(月) 14:33:16
programminglang::C::namespaceでいいよ。
namespace 入れてくれれば enum を気兼ねなく使えるしな namespaceだとC++と同じだから、miniascapeでCに取り込んだらどうだろうか
普通に namespaceでいいよ。だからさっさと取り込んでくれ。
namespiceでいいよ
776 :
デフォルトの名無しさん :2009/04/20(月) 22:20:40
namaespaceでいいよ
777 :
デフォルトの名無しさん :2009/04/20(月) 23:33:28
namaekukanだろjk
無名名前空間も頼む。 staticいちいち付けるの面倒なんじゃ。
C++にて #include "child/inc.h" みたいに子フォルダにあるファイルのインクルードは認められているんだよね?Boostにもあるくらいだし。 #include "../my_typedefs.h" みたいに親フォルダにあるファイルのインクルードは認められている?
>>779 残念ながら #include の指定と実際のファイルとの対応付けはほぼすべて実装依存。
規格で決まってるのは "" が <> の検索範囲を含むということだけ。
いまだにディレクトリ階層の存在しないシステムでの実装も存在できるようになってるってことか。
782 :
779 :2009/04/21(火) 14:51:51
>>780-781 そうなのか。ありがとう。
・・・まあつまり、その環境でインクルードできて動けばいいよってことね。
コメントって、「だ・である調」で書く物ですよね? 「です・ます調」じゃないですよね?
英語で書くものですよ^^
英語かぁ。 そうなんですね。
「ニダ・セヨ調」
誰に読ませるコメントかってことだよ。 自分用のメモ代わりならどう書こうと完全に自由だし日本語表示できる環境の人だけしか読まないだろうっていうなら日本語でいい(文字コードには気を配る必要はあるけどな)。
それと多バイト文字に対応してない・対応が甘いソフト使ってる環境では問題がおきるときがあるのでそれも配慮がいるな。
>>783 「だ・である調」でコメント書いてる商用ライブラリってみたことある?
みんな「です・ます調」だよね。
あ、自分は「だ・である調」^^;
俺も学生時代から英語でしか書いたことない
791 :
デフォルトの名無しさん :2009/04/21(火) 20:34:35
英語でコメント書いたら負けだと思う。 日本語で書くか、書かなくてもいいように関数名にひたすら意味を込める。
しかし関数名は英語だ。
793 :
デフォルトの名無しさん :2009/04/21(火) 20:40:29
関数名の英語は敗北ではない。
794 :
783 :2009/04/21(火) 20:41:42
>>784-792 なるほど、皆さん自説がおありで意見が割れるものなんですね。
ありがとうございます。
double standard
変数名は日本語だけど、英語でコメント書く。
いつまでやってんだよしねよカス
void F() { puts( "F()" ); } struct Test { typedef boost::function<void()> func_t; Test( func_t ) { }; void F() { } }; int main() { Test t( Test::func_t( &F ) ); t.F(); return 0; } これ通らないんだけど、なんで? ctorが関数宣言に解釈されてる?
>>798 末尾空白を除去するフィルタやDoxygen対応も考えて、ドットを推奨しておく。
>>799 何はともあれ、エラーメッセージを貼るべき。
801 :
デフォルトの名無しさん :2009/04/21(火) 22:52:24
Test( func_t ) { }
main内でのTest t(...が関数宣言と認識されちゃってるね(on gcc-4.1.2) 最初の引数を型名以外にしたら変数宣言になったけど、最初が型名なら 関数宣言になるとかルールがあるのかな?
Test t = Test::func_t( F ); とか
>>802 そう、変数宣言とも関数宣言とも取れるときには、関数宣言として解釈されるということ。
>>803 とかTest t( (Test::func_t( &F )) );と書くのが直接的な常套手段。
>そう、変数宣言とも関数宣言とも取れるときには、関数宣言として解釈されるということ。 そんなルール何処に書いてる?
書いてないよ。
そんな重要なことを書いてないわけ無いだろwwww 実際書いてあるし
残念ながら書いていない。実装依存。
おまえらが必死なのはわかるが レス時間の短さから信憑性が低いといわざるをえない
>>804 thx
俺もTest t = ryでわーくあろうんどしてた
()でくくると評価順が変わる?
ついでに、 Test( func_t ) だとコピーコストかかりそうだったから山椒にした constかからんし、結局1行での初期化諦めたわー まぁほんとにthx
>>805 ほか
8.2、JIS X 3014 : 2003だと「あいまい性の解決」の箇所が該当する部分。
> 関数型のキャストと宣言との間の類似性から起こるあいまい性(6.8参照)は,
> 宣言の文脈においても起こりえる。この文脈では,仮引数名を囲む括弧を冗長に持った関数宣言と,
> 関数型のキャストを初期化子として持つオブジェクト宣言との間の選択となる。
> 6.8に示したあいまい性に対しては,宣言となる可能性のある構文は宣言とすることで解決法とする。
> 参考 関数型でないキャストを使うこと,初期化子を示すのに“a =”と記述すること,
> または仮引数名を囲む冗長な括弧を除去することによって,
> 宣言を明示的にあいまい性のないものにすることができる。
この後に例がいくつか続くんだけど省略
#define CASE(X,F) case X: F(); break; これを上手い事クラスに出来ないものだろうか
815 :
デフォルトの名無しさん :2009/04/22(水) 15:52:17
class X{public: void F();}
複素数の配列について質問させてください。 resizeを使いたいためにstd::vectorで定義した配列でcomplex<double>を代入するにはどんな方法を取ると良いでしょうか? 宜しくお願いします。
>>816 質問の意味がよくわからないが
vec[0] = std::complex<double>(1.0, -1.0);
のようにコンストラクタで一時オブジェクトを使うとかそういう意味?
>>814 エスパーしてみる…
class BaseCase
{
public:
static BaseCase* Create(int condition);
BaseCase(){}
virtual void F() = 0;
};
class CaseA : BaseCase {
public:
void F(){ printf("Case A\n"); };
};
class CaseB : BaseCase {
public:
void F(){ printf("Case B\n"); };
};
BaseCase* BaseCase::Create(int condition){
switch(condition){
case X: return (BaseCase*)(new CaseA());
case Y: return (BaseCase*)(new CaseB());
}
}
int main(int, char**){
BaseCase* obj1 = BaseCase::Create(X);
BaseCase* obj2 = BaseCase::Create(Y);
obj1->F();
obj2->F();
}
>>818 auto_ptrとかshared_ptrとか使えよ。
まぁ関数オブジェクトをコンテナに入れろよと
ハッシュ比較がジャンプテーブルになるならコンテナでもいいけど コンパイル時は無理臭い
822 :
816 :2009/04/22(水) 20:33:30
>>817 お返事ありがとうございます。
1次元の配列に複素数を使いたいのですが、std::vectorを使用するとdoubleやintで上手くいく処理もcomplexだと上手くいかずに困っているのです。
ご指摘の方法も試したのですが、
> sample.cpp(56) : error C2440: '=' : 'std::complex<double>' から 'double'に変換できません。
> この変換を実行可能なユーザー定義変換演算子がないか、または演算子を呼び出せません。
このようなエラーが出てしまいます。
std::vector<std::complex<double> >にしている? そんなエラーが出ると いうことは、std::vector<double>にしているようにしか思えないのだけど。
>>822 そのエラーの起きたコードを張ってくれ。
>>822 まさか
>>823 なのか?俺も一瞬そう思ったけどさすがにそれはないよなあと
思って書かなかったんだが
こんなところまでモンペが入り込んできたか
モンペって何? ノンケなら食っちゃうけど^^
きもい
細かい事なんですが、 インクルードするヘッダは、ヘッダの中でインクルードされたヘッダも考えて、必要最小限にした方がいいんですかね? それともヘッダの先で何がインクルードされてるか気にするより、使うもののヘッダ全部インクルードするべきですか? #include "Hoge.h" Fuga fuga = hoge.GetFuga();// 明らかにFuga.hはHoge.hでインクルードされてそう std::vector<int> vec; // Hogeの内部で使われてたvectorがdequeに変更されたらエラーに
>>829 ヘッダの中まで気にする手間をかけ、ヘッダの中身への依存関係を増やして、
いったい何が得られるというのかね?
>>830 コンパイルにかかる時間が短縮されるかなーと(冗長インクルードガードにすると速くなると聞いた記憶が)。
>>829 の例の場合、Fuga.hもインクルードしますか?
832 :
デフォルトの名無しさん :2009/04/23(木) 02:30:51
LCG dictionary についてわかりやすい解説サイトがあったら教えて下さい。
>>831 俺ならvector, Fuga.h, Hoge.hすべてインクルードする
Effective C++にて「異なる翻訳単位で定義されたローカルでない静的オブジェクト」の初期化の順番の問題を読みました。 これは、そのローカルでない静的オブジェクトを無名名前空間に入れてしまえば、そのファイルに対してだけ有効なスコープとなるので、問題はありませんよね?
std::overflow_error, std::range_errorなど、 標準の例外クラスは皆what()メンバ関数を持っているものですか?
>>836 その名前空間内に extern を一個も書かないなら問題ないです
書くなら問題あるかもね…
3.6.2に、初期化順序の説明と未規定になってしまうコード例が掲載されてます
>>837 もってます
839 :
836 :2009/04/24(金) 17:42:23
>>838 その無名名前空間の中にあるものを外部からexternしようとしてももちろん出来ないので大丈夫で、
またその無名名前空間の中から外部の変数をexternしないように気をつけてあります。
ありがとうございました。
841 :
836 :2009/04/24(金) 20:15:54
>>840 Nifty_Counterイディオムって
なんだかややこしそうですね。
よく読んでみます。
842 :
837 :2009/04/24(金) 20:26:45
>>838 ありがとうございます。
boostの例外クラスなどが持っていて、
またいくつか調べた標準例外クラスも持っていたので、
もしかするとと思っていました。
あるクラスMyClassのメンバ関数m_func()の戻値(boost::shared_ptr<MyClass>型)が有効な場合と無効な場合があり、 有効な場合はそのまま使えるが無効な場合はエラーメッセージを取得するようにしたい。 ただしこのメンバ関数m_func()は例外を投げさせたくない。 この場合はどうすればいいと思う? 俺としてはboost::variantで boost::variant<boost::shared_ptr<MyClass>, std::string> を返す様にし、呼び出し側でその返り値を検査する方法を考えているのだが、 もうちょっとエレガントな方法はないかなぁ?
例外にエラーメッセージを乗せるのが一番エレガントだろ。
MyClass_exception構造体でも宣言しといて、std::string型の例外を投げるとか?
846 :
845 :2009/04/25(土) 17:40:17
ごめん意味不明なこと書いた。 気にしないで
847 :
843 :2009/04/25(土) 17:50:21
やっぱ例外使うかぁ。 ありがとう。
質問なんだけど try { //**例外を投げるかもしれない処理**// } catch(const expected_error1 &ex) {throw ex;} catch(const expected_error2 &ex) {throw ex;} catch(const expected_error3 &ex) {throw ex;} catch(const expected_error4 &ex) {throw ex;} catch(const expected_error5 &ex) {throw ex;} catch(...) {throw unexpected_error();} このように、 //**例外を投げるかもしれない処理**// の部分で生じた例外が予想の範疇(expected_error1~5)の場合は例外をそのまま外に投げ、 想定外の例外の場合にはunexpected_error構造体を投げたいという場合は上のようなコーディングになると思うのだが、 これ以外にはどうしようもない? expected_error1~5は独立した型で、継承関係はないとして。
再送出ならthrowだけでいいんじゃない? ぐらいで特にない
>>849 >再送出ならthrow
そうなんだ!
ありがとう。
質問なんだけど、 class MyInt { public : int num; 各種メンバ関数 } このように自分でintをラップしたクラスを作った。 このままだとMyIntが表現できる値がint型の取れる値に限られるので、 これにスペシャルな値として special_val1, spcial_val2, special_val3, special_val4 の4つを取りうるようにしたい。(例えば無効値を表すとか∞を表すとか考えてる。) どういった実装にすればいいかな? unionとか使うの?
まず、ラップされてないからnumをprivateにあげる。 いつスペシャルになるのかわからないけど、 メンバ関数でアクセスされたときにスペシャルな時だったら スペシャルな値を返すようにすればいいと思うよ。 別にnumのメモリと同じ位置にスペシャルな値が入ってなければならないというキマリはないから。
>>851 enum { normal, invalid, infinite } で、 num は normal のときだけアクセスできるようにする、
とか。
854 :
851 :2009/04/25(土) 23:30:44
メンバ変数の配列の初期化ってどうすればいい? 例えば class MyClass { const int num; public: MyClass(); //メンバ関数 }; これだったら MyClass::MyClass() : num(42) {} だよね。ではconst int num;がconst int num[3];だったら num[0], num[1], num[2] のコンストラクタによる初期化はどうすればいい?
class MyClass { static const int num[3]; public: }; const int MyClass::num[3] = { 1, 2, 4 }; staticにしてしまう(キリッ)
ググればわかることだけど 敢えて別の解を検討してみる class MyClass{ const int (&num)[3]; MyClass(const int (&_num)[3]):num(_num){}; }; func(){ const int num[3]; MyClass myclass(num);
>>856 なるほど、申し訳ないんだが、実はコンストラクタの引数で初期化したい。
すなわちclass MyClass
{
const int num[3];
public:
MyClass(int first, int second, int third);
//メンバ関数
};
MyClass::MyClass(int first, int second, int third) : num[0], num[1], num[2]を引数で初期化
{}
だった。まあconstあきらめてコンストラクタで代入すりゃいいんだけど。。。
>>857 配列への参照をメンバに持たせるってことか。面白そうだが。
あるクラスのインスタンスを生成させず、 継承しても生成できないようにすることはできますか? たとえば 1.デフォルトコンストラクタだけを定義し、private指定する。 2.デストラクタを純粋仮想として定義し、private指定する。 この2つを行えば大丈夫ですか?
C++0xのinitializer_listで MyClass(int fst, int snd, int trd) : num({fst,snd,trd}) {} とかできないのかなぁ…(gcc-4.4では駄目だったorg)
まだ0xって名前何だっけ
>>858 unionって初期化子で使えないんだっけ?
class A{
union{
int a1,a2;
int a[2];
};
public:
A():a1(50),a2(200){}
};
みたいな。試してないけど
>>860 それやるなら
MyClass(int fst, int snd, int trd) : num{fst,snd,trd} {}
じゃね?()付けると意味が変わると思う
>>858 boost使っていいなら
#include <boost/array.hpp>
#include <boost/assign.hpp>
class MyClass
{
const boost::array<int, 3> num;
public:
MyClass(int first, int second, int third);
};
MyClass::MyClass(int first, int second, int third)
: num(boost::assign::list_of(first)(second)(third))
{
}
くらいかな
boost::array<int, 3>はstd::vector<int>で置き換え可能です
>>859 1だけで大丈夫だと思う
不安ならコンストラクタの中にassert(!"生成しないで")って書いとけばおk
865 :
858 :2009/04/27(月) 16:50:13
>>864 boost::arrayって単なるラップだと思ってたわ。
boost::assign::list_of(first)(second)(third)で初期化できるんだね。
初めて知ったわ。
ありがとう。
多倍長整数や多倍精度小数クラスを使いたい場合どうしてる? 自作してるとか、仕事先にライブラリがあるとか、 フリーでライセンスの制限の緩いものを商用利用しているとか?
組み込み向けでunsignedな64bit整数が欲しかったので自作した。
multi precision library
同じスコープ内に enum GET { AAA }; enum SET { AAA }; ってやると、コンフリクトしちゃうの? セットする値と、ゲットする値を訳て面倒な分岐処理をなくそうとか思ってるんだけど、 structとかでラップするしかないのかなぁ?
>>870 共通にして一個にまとめればいいんじゃないか?
Enumの内容が外のスコープにまき散らされるのは勘弁して欲しいよな
0xでenum classが導入されるまで我慢するんだ
分岐無くすだけでいいなら enum GETorSET{AAA,BBB,amountGETorSET}; enum GET{GET_AAA=9,GET_BBB=10}; enum SET{SET_AAA=11,SET_BBB=4989}; int get(GETorSET _x){ const int enumGET[amountGETorSET]={GET_AAA,GET_BBB}; const int x = enumGET[_x]; } bool set(GETorSET _x){ const int enumGET[amountGETorSET]={SET_AAA,SET_BBB}; const int x = enumSET[_x]; } でいいんじゃないか?
875 :
デフォルトの名無しさん :2009/04/28(火) 21:01:12
>>866 色々ライブラリがあるけど、えらく巨大だったり充分デバッグされていなかったりなにより
ドキュメントがしっかりしてないのが大杉...
結局自作した
>>875 で、お前は十分デバッグしてドキュメントもしっかり書いたんだよな?
877 :
デフォルトの名無しさん :2009/04/28(火) 23:34:22
>>876 公開してるわけじゃないから手元のノートだけ
878 :
866 :2009/04/29(水) 00:19:21
>>875 >色々ライブラリがある
例えば何があった??
なんかみつかんねぇんだよなぁ、ライセンスが厳しくて。GPLとかむちゃ言い過ぎ。
opensslに入ってなかったっけ?
多倍長整数ライブラリ bn で検索すれば使ってるの見つかるな
881 :
878 :2009/04/29(水) 00:30:52
>>879-880 おお、ありがとう。
さっそく調べて検討してみるわ。
俺が自作すると
メモリ効率悪く・遅く・バグがあり・枯れていない・信用がない・車輪の再発明
的なデメリットばっか思いつく。
MIRACLなんかはドキュメントもしっかりしてるし、商用にも対応できるよ 商用の場合は無料じゃないけどね 自作するときはknuthのThe Art of Computer Programming Vol.2を参考にするといいよ
>LGPLだとライセンスが厳しすぎるなぁ。 いったい何を企んでるんだ。
あるクラスAAAがあったとしてAAAのコンストラクタで整数を引数に取るとき メンバー変数にクラスAAAのインスタンスaを持つクラスBBBを class BBB { public: AAA a (10); }; こんな感じに書きたいんですけど、これをコンパイルすると 構文エラー:定数 って言われて怒られます!どうして!?
整数への参照を引数に取ってるとか?
>>884 関数とみなされるから
C++0xからそういう風に書けるようになる
>>884 通常のC++でこの問題を回避することはできませんか?
>>884 class BBB
{
AAA a;
public:
BBB() : a(10){}
};
>>888 なるほど、そういう方法があるんですね
ありがとうございます
>>886 >C++0xからそういう風に書けるようになる
マジか。それ絶対便利だな。すばらしい改良。
>>883 LGPLって再配布時にソース公開だよね?これって厳しい条件じゃない?
>>893 いやそういうつもりはないんだけど、
もしかしてGMPを使って実装したプログラムを配布する場合
のソースコードの公開は不要なのかい?
例えば静的リンクでも?
リバースエンジニアリングを禁止できないってのがなぁ 個人的にはどうでもいいけど仕事で使いにくい
LGPLだとdllが巨大になるんだけど どうにかならないかなあ
FDDに入れるわけじゃあるまいし、気にすんな
899 :
デフォルトの名無しさん :2009/04/30(木) 01:39:52
LGPLは関係ないだろ。 デバックにしてるとかだろ
900 :
894 :2009/04/30(木) 06:47:57
>>895 ありがとう。
そうだったのか。GPLと大差ない物かと思っていた。
>ライブラリAに静的リンクしたプログラムBを配布する場合、
>Bのソースコードまたはオブジェクトコードの配布を拒否してはならない。
これは恐ろしい。。。
静的リンクはやめたとして、それでもなおリバースエンジニアリング禁止が
できないっていうのは諦めるしかないよね。
業務で使うならライセンスのはっきりしてるライブラリを購入するのが無難かも。
902 :
900 :2009/04/30(木) 19:08:41
>>901 ですかねやっぱ。
趣味で使うなら色々いけるんだろうけどねぇ。
ありがとう。
ライセンスがはっきりしないものなんてGPL云々の前に業務じゃ使えんだろ
904 :
デフォルトの名無しさん :2009/05/01(金) 09:49:38
その前に仕事探せよ
void f( const int* begin_p, const int* end_p ); main() { vector< int > v; f( &*v.begin(), &*v.end() ); // <- ここでイテレータの不正アクセス例外 } このようなコードだと、v.end()のアドレスを得るところで落ちるケースがあります。 (C#から↑のようなコードが含まれたC++DLLをコールした場合など) v.end()をポインタ参照せずにアドレスを得る方法などありませんか? 「&*v.begin() + v.size()」は駄目でした。
&v[0]
>>905 &*v.begin() + v.size()でいいと思うんだが。
ただvが空だと&*v.begin()も駄目だろう。
>>905-906 空の vector には要素が無いんだけど、何のアドレスを得るつもりなの?
>906 も未定義動作ね。
empty() なら両方ぬるぽでも渡すようにすればいいような気がする。
909 :
デフォルトの名無しさん :2009/05/01(金) 14:12:33
駄目とはどういう状態のことを指していっているのか説明しろとあれほど言っ(ry
空の vector に対して *v.begin() の時点で未定義動作になるから、 ここで assert() かなんかにひっかかるんじゃないかな?
912 :
デフォルトの名無しさん :2009/05/01(金) 14:23:55
v[v.size()] は int型 &v[v.size()]は int*型
v[v.size()]なんてやったら常に範囲外アクセスじゃないか
>>912 型は正しいが空の vector v に対して評価すると未定義動作。
915 :
914 :2009/05/01(金) 15:23:34
って、 v.size() か。なら
>>913 のいうとおり空じゃなくてもアウトだ。
v.end()のアドレスなんか取ってどうするのだろう
結論 f(&v[0], &v[0] + v.size()) なら、!v.empty()の時は常に大丈夫 v.empty()の時は、(実装によっては大丈夫なものもあるが)未定義動作
918 :
デフォルトの名無しさん :2009/05/01(金) 16:21:44
アドレスとサイズ渡せばすむことだ
早く f(v.data(), v.data()+v.size()) って書けるようになるといいな
vectorに先頭と最後の要素を指すポインタを返すbegin_p()とend_p() というのを追加して、 f(v.begin_p(), v.end_p()) って書けるようにするのが一番素直
>>920 最後の要素を指すポインタを返すend_p()ってのは
end()と統一性が無くて紛らわしかないか?
無効要素への&演算子が実装定義の解釈だけど 戻り値が不定なだけで異常終了はしないとか、規格はそうはなっていないの? そもそも、やること自体が危険だという意味の実装定義と 得られる値が実装系で決まる(不定値含む)という意味の実装定義に区別はないの?
規格の上では鼻から悪魔なんじゃないの
>922 不定(unspecified)、未定義動作(undefined behavior)、処理系定義(implementation-defined)は全て異なる概念です。
front/backでいいじゃん。
end()未満まで反復するのがイテレータの考え方だから、back()を終わりに指定すること自体に違和感。
[begin, end)か
>>907-911 >&*v.begin() + v.size()でいいと思うんだが。
自分もそう思うんですが、VCのアサートマクロに引っかかってしまいます。
(vector iterator not dereferencableと出る)
仮に、vにダミーの要素を1つpush_back()して、
「&*v.begin() + v.size() -1」とすると出なくなります。
C++のホストから問題のC++のDLL(デバッグビルド)を呼ぶと出ないのですが、
C#のホストからC++のDLLを呼ぶと出ます。なので、デバッグトレースで追えない。
>空の vector には要素が無いんだけど、何のアドレスを得るつもりなの?
すみません、実際は空のチェックはしてました。
>>925 f( &v.front(), (&v.back())+1 );
でも同様に駄目でした。
なんとなく他のバグの影響のような気がします。
f()の中でend_pを参照するようなバグがあるか、
そこらへんを調査してみます。
アドバイスありがとうございました。
>>928 空のチェックをして、空じゃないときに &*v.begin() してれば
"vector iterator not dereferencable" とはならないはずだ。
空のチェック含めたなるべく実際のものに近いコードを晒せ。
変に省略するのは良くない。
そういう使い方ができるvectorを再発明しちゃえばいいんじゃね みんなテンプレート覚えたての頃に必ずvectorみたいなものを自作してるってばっちゃが言ってた
Effective STL の第16章にずぶりやり方が書いてあるね。スコットかわいいよスコット。
拡張子.hppというのは.hと同じ意味だと聞いたが、 たまにippとかいう拡張子を見ることがある。 ただのテキストファイルっぽいんだけど、これは何物?
インライン関数 デバッグ版では.cppに、リリース版では.hにincludeするために分離してるファイル
なるほどなるほど! 全て合点がいった! となると、一応分類するなら .cppの仲間ではなくて.hないし.hppの仲間ってことね。 ありがとう!!
using namespace my_ns; って書けるのはどのスコープまで? グローバルスコープだけしか書けないとか? ・・・と思いきや自作の名前空間の中にも書けたり、クラススコープ内には書けなかったりと よく分からない。。
クラススコープ内ではusingは違う意味に変わるから書けない
そういう事だったのか。 usingで外部のを引っ張ってくるアレね。 サンクス
板違いだけどおしえてくだしあ linux+emacs+C++で開発してるんだけど、単体開発のスマートなやり方を教えてください 単純にみんなg++ hoge.cpp -c とかやってコンパイル通るかどうかやってるの? もしくは、hoge.hpp/hoge.cppごとにmakefile書くとか? なんかVisualStudio厨だったから、こういうのが非常に面倒で開発遅れぎみです。 助けてください!誰か、助けてください!
まずはMakefileの書き方覚えて挙動を理解することからじゃないか? そしたら >hoge.hpp/hoge.cppごとにmakefile書くとか? なんて質問が出るわけない。
>>942 いやまぁMakefileは適当に書き方覚えただけで、autotools使うようになっちゃったんであれなんだけど。
Makefileの書き方知ってる人はどうするんですか?
>>941 VisualStudioだとコンパイルする前にコンパイル通るかどうかわかるの?
>943 suffix rule か pattern rule を使って、ファイル毎にルール書いたりはしない。 そもそも組み込みのルールがあるんで suffix rule とか書く必要もない場合も多い。 Visual Studio でファイルを追加するのと同じようなレベルで Makefile を書いて、 Visual Studio でビルドするのと同じようなレベルで make 打つだけ。 依存関係の処理は多少問題だが、Autotools 使ってるならそれでいいんじゃね?
946 :
デフォルトの名無しさん :2009/05/04(月) 11:52:56
演算子の優先順位について教えてください。 下のコードの a?b:c = 4; のところは ?: よりも = の方が優先順位が低い為、 (a?b:c) = 4; の意味になるはずだと思うのですが、 私の環境で動作させると、 a?b:(c=4); の動作をしているようで、 bに4が代入されずに main の戻り値は2になります。 これはC++の仕様でしょうか?それともコンパイラのバグでしょうか? コンパイラはVisual C++ 2005です。 int main(){ int a=1,b=2,c=3; a?b:c = 4; return b; }
仕様
>>946 俺も何がおきてるんだろうかと考えてみた。
> ?: よりも = の方が優先順位が低い為、
> (a?b:c) = 4; の意味になるはずだと思うのですが、
正しい。
> a?b:(c=4); の動作をしているようで、
ここは間違いじゃね?
> コンパイラはVisual C++ 2005です。
g++でも2が返ったよ。
俺の考えでは
a?b:c
の返り値であるテンポラリオブジェクト(int型の値2をもつ一時変数)にたいして = 4;
が実行される。実行直後にそのテンポラリオブジェクトは要らなくなるので破棄される。
その後、何事もなかったかのように
return b;
が実行され、bの値である2が返るとか。
949 :
948 :2009/05/04(月) 12:35:22
>>946 実際に、cの値を返させると4でなく3が返ってくるだろう。
>>947 仕様ではないと思う。
C++の仕様では組み込み型の一時オブジェクトの値を変更したら
動作は未定義となるのでは?
すなわち今回の場合、mainの戻り値がいかなる数字でも
あるいは鼻から悪魔が出てきてもおかしくないのでは?
950 :
デフォルトの名無しさん :2009/05/04(月) 12:35:30
>>947 ありがとうございます。
できれば、なぜ = の方が強くなるのかの説明をしていただけるとうれしいです。
>>948 cの値が3なのは
a?b:(c=4) で a != 0 の場合は c=4 が実行されないからだと思います。
以下のようにすると、bと(c=4) の型が異なるのでエラーになりますが、
(a?b:c) = 4; とするとコンパイルが通ります。
やっぱり a?b:(c=4) となっているのだと思います。
class T {
public:
int operator=(int n){
return 0;
}
};
int main(){
int a=1;
T b,c;
a?b:c = 4;
return 0;
}
947です ごめんなさい 値返しだったみたいですね
>948 そーいうことはせめて (a?b:c) = 4; を実行してみてから言うべきじゃね? > 14882:2003 5.16/4 > If the second and third operands are lvalues and have the same type, the result is of that type and is an > lvalue. なので a?b:c なら左辺値が返るので代入はそのまま動作する。 >949 >実際に、cの値を返させると4でなく3が返ってくるだろう。 a?b:(c=4) で a は真になるから c=4 は評価されない。 >950 構文的に > conditional-expression: > logical-or-expression > logical-or-expression ? expression : assignment-expression > assignment-expression: > conditional-expression > logical-or-expression assignment-operator assignment-expression > throw-expression logical-or-expression はもっと優先順位の高い演算子を含む式ね。 assignment-expression の左辺には logical-or-expression 以上のものしか現れないので、 conditional-expression が直接現れることはできない。 一方、conditional-expression の第2、第3引数には assignment-expression が現れることが可能 (expression は任意の式を含む)。 conditional-expression が三項演算子なので二項演算子等の単純な優先順位の話とは異なるということだと思われ。
>>951 左辺値をそういう指定しちゃダメじゃないか?
想像や憶測で答えるなよ……。 規格票で条件演算子のところを見てみようぜ。 > 5.16 二択条件演算子 > 二択条件式: > 論理和式 > 論理和式 ? 式 : 代入式 コロンの後ろには代入式が来ると定義されているのでa ? b : c = 4はa ? b : (c = 4)と解釈される。 条件演算子が代入演算子より優先順位が高いというのは「a = c ? 1 : 2」のような場合。 なお、C++では括弧付けて(a ? b : c) = 4と書けば、bまたはcに4が代入されるという意味になる。 ANSI Cと違ってbとcが同じ型の左辺値なら、条件式の結果も左辺値になるためエラーにならない。
956 :
948 :2009/05/04(月) 13:10:19
本当だ、規格引いてなかった。 吊ってくる。
>>953 >>955 ありがとうございます。
演算子には単に優先順位と結合規則以外にも
いろいろなルールがあるんですね。
すごく複雑。
あるクラスのprivateメンバとして 同時にアクセスされない2つのメンバ変数int iとchar cがあるとき、 これらをunionでまとめるとメモリが節約できるとの事だけど、 これは代償として遅くなる? structでまとめた方が速かったりする?
959 :
デフォルトの名無しさん :2009/05/04(月) 14:39:44
遅くならない。 速くない。
961 :
960 :2009/05/04(月) 14:44:33
×unionのが言い訳 ○unionのが良いわけ
>同時にアクセスされない2つのメンバ変数int iとchar cがあるとき、 この言葉で,unionの危険性は回避されない
963 :
デフォルトの名無しさん :2009/05/04(月) 14:47:43
964 :
デフォルトの名無しさん :2009/05/04(月) 14:49:27
>>958 メンバ変数int iを持つクラスと、char cを持つクラスを別に作った方がいいんじゃない?
ヒント。変数は値を保存する機能が本質だ。アクセスは、それを見るだけ。
966 :
デフォルトの名無しさん :2009/05/04(月) 14:50:40
ヒントは要らないから、具体例を。
うまく説明できないから、「ヒント」と言ってごまかしているわけで。 あまりいじめるなww
賢いあなたが、代わりに説明をどうぞ
969 :
960 :2009/05/04(月) 14:53:12
>>962 2つのメンバ変数int iとchar cに同時にアクセスせず、
その値を取り出す時は現在どちらの値として入っているのかを
ちゃんとチェックして取り出すつもりだったんだが
それだけではunionは危険なのかい?
俺はこの条件で大丈夫だと思っていたのだが。。。
970 :
デフォルトの名無しさん :2009/05/04(月) 14:54:17
危険じゃないよ。
971 :
960 :2009/05/04(月) 14:55:32
>>970 だよね。
別にビット列を利用して適当な型の最初の1バイトだけ覗こうとか
そうゆうこともするつもりないし。
>その値を取り出す時は現在どちらの値として入っているのかを >ちゃんとチェックして取り出すつもりだったんだが この説明が入っていれば問題はない。 後出しじゃんけんんの勝利おめでとw
世の中には、union、gotoと聞くだけで、脊椎反射で危険危険と言う奴がいるからw
次はレッテル張りか、おめでたいやつ
後だしジャンケンのレッテル貼りか、おめでたいなw
976 :
960 :2009/05/04(月) 14:59:13
>>972 煽らないでくれよ、
俺は喧嘩したいわけじゃないんだ。
みんな仲良くしてくれ、俺の質問のために喧嘩しないでくれ。
教えてくれた人たちありがとう。
>>969 そういう仕様がほしいなら、boost::variantを授けよう。
>>973 知って使えば有用だし、濫用すれば毒になる。
毒にも薬にもなるって典型だよね。
979 :
960 :2009/05/04(月) 15:04:56
>>977 boost::variantってあったねぇ。
便利そうだが、遅くならないか心配な面もある。
遅くなるわ、メモリが節約できないわ、もうね。
>>980 あれってメモリ節約できないんか。
じゃあ一方を有効にした時 他方へアクセスできないようにしなきゃならない事情のある時に使う代物か。
>>969 チェック処理を入れるなら、チェック処理の分遅くなるんじゃない?
要素が巨大なstruct2つとかだったら節約になるかもしれないが、intとcharなら使用メモリは確実に増えるね。
984 :
960 :2009/05/04(月) 15:13:03
>>982 必ずしもチェック処理入れるつもりはありません。
状況次第で確実にどちらか判別付くならチェック処理しません。
例えばある関数fooから呼び出した時はunionのint xの方へアクセスすることが確実で、
しかも前後関係からunionのint xが必ず有効だと分かっているなど。
985 :
960 :2009/05/04(月) 15:13:59
>>983 ああ、intとcharは引き合いに出しただけで、デカめの自作クラスを入れるつもり。
ならunionでいいね。boost持ち出すまでもない。
流れ無視、それで節約されるメモリに余計なコードと管理の手間を増やすことに見合うほどの価値があるのか?。
988 :
デフォルトの名無しさん :2009/05/04(月) 15:47:19
メモリに余計なコードと管理の手間がなければ、節約された方がいいでしょう。
>>987 価値があるかどうかはその人の価値観と状況の差だと思う。
組み込み系だったりするとまた話も違うだろう。
>>985 クラスならPODじゃないと入れられないから気を付けろよ
>>987 チェックされるならデバッグが簡単になる。
>>990 そういやそんな制限もあったなぁ。unionなんて久しく使ってなかった。
次スレは誰が建ててくれる?
multisetのoperator>ってどういう動作ですか? もしくはそう言ったのが分かる参考サイト教えてくださいませんか?
999get
人生初の1000をとりましたよ。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。