【C++】 const だけでメシが3杯食えちゃうスレ

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
C++で多用される const について疑問、質問、語り等なんでも書き込んでくれ。
mutable
constってなんですか?
>>3
「値が変わらないよ」って意味だといいんですが…。
ポインタ
からむと ちとかわる
6デフォルトの名無しさん:04/03/02 11:42
delete >>1;
constが嫌いなので、const使わないでプログラムする方法無いですか?
使わなけりゃいいだけじゃないのんか?
>>5
const 書く場所による
例えば、コピーコンストラクタってやつで、

Test( const Test &hoge )

と書いてあるときのconstは何の意味があるんですか?
>>10
hogeは変更しないよって意味
hogeは書き換えちゃダメよって意味
でもデータメンバが全部mutableだったらたぶん意味ないよって意味
const_cast
constは頻繁に、volatileはたまに使うけど
mutableは一度も使ったこと無いな。
存在自体を忘れていた。
1410:04/03/02 14:24
>>11
う〜ん。なるほど。
つまり、代入元となるhogeを保護するために付けるんですね。
でもコピーコンストラクタが呼ばれた時にhogeが書き換えられる
危険性ってあるんですかね〜?
書き換えられる危険性があるかどうかではなくて
呼び出す側が、引数として渡されるオブジェクトを変更しないという保証のため

const string a("CONST");
に対し、
string b(a);
が使えるかが問題。
(bを変更するかどうかは、この場合問題にはならない)
void foo() const;
ってなによ?
1710:04/03/02 14:39
>>15
どんな香具師に渡されるかわかんないから保証しとけってことですね。
なんとなく解かった気がした。
>>16
foo()は変更を伴う操作を行わない
>17
ちょっとわかりにくかったけど、要は
呼び出し側の都合でconstなものしか渡せない場合があるってこと。
その場合でもエラーにならないようにするには
引数をconstとして宣言するしかない。

それと、引数が const & の場合
暗黙の型変換が適用できる(される)というのもある。
>>16
constなインスタンスでも使えるようにする。

struct Foo {
 void foo() { std::cout << "foo"; }
};
struct Bar {
 void bar() const { std::cout << "bar"; }
};

const Foo foo;
const Bar bar;
foo.foo(); // error
bar.bar(); // OK.
>>20
const宣言すると外部からアクセスできないけど、内部でもう一回const宣言
してあるとアクセスできるようになるというのは仕様と考えればいいんですか?
意味不明なこと書くな。

const宣言してあるオブジェクトは変更できないから
変更する可能性のあるメンバー関数を使うことは出来ないけど
constなメンバー関数は自信を変更しないことを保証しているから
constなオブジェクトから使うことが出来る。
それだけのこと。
>>17 に書いてあることを全く理解していないな。
const地獄
非参照で非const な型 T と、const , ポインタ 参照の組み合わせ( C++ )

T const
T const &
T * const
T * cosnt &
T const *
T const * &
T const * const
T const * const &

( & const はコンパイラが警告を出すので除外 )

template< typename T >
struct add_const { typedef T const type; };

template< typename T >
struct add_const< T const > { typedef T const type; };

template< typename T >
struct add_const< T & > { typedef T const & type; };

template< typename T >
struct add_const< T const & > { typedef T const & type; };
template< typename T >
struct remove_const { typedef T type; };

template< typename T >
sturct remove_const< T const > { typedef T type; };

template< typename T >
struct remove_const< T const & > { typedef T & type; };
>>26
2、4番目の特殊化は要らないんじゃないか?
難しいな〜。初心者のオレにはわけわかめ
>>28
T const const って T const になるんだけっか。
だとすれば確かにいらないね。
3126:04/03/02 18:05
>>28
そうですね。確かに不要でした。
よく出来てるネ。

32デフォルトの名無しさん:04/03/02 20:04
>>16のって、キッチリ書くと

void foo() const { }

になるんでつか?
const constがconstになるのにreference referenceに文句を言われるのは不公平
>>32

class Hoge {
  ...
 void foo() const;
  ...
};

void Hoge::foo() const { ... }

でも可。
値返しの関数の返り値型を必ずconstにしてるんだけど,これって問題ない?
constつけられるところには必ずつける癖をつけてるんだけど・・・
むしろ意味がない
あ,返り値の一時変数に代入するような意味のない記述を
コンパイルエラーで弾く意図があるんですが・・・やりすぎですか?
しばらく使っていると、他人に操作されないために const をつけるのではなく
自分がポカミスしないために const つけてます。
高速化目的等にも役に立つけれど、主な目的はバグ防止だよね。
コンパイル段階で弾けるエラーが増えるとというのはデバックが短時間化できていいよ。
最近は、これの派生でテンプレートを使ったコンパイルタイムアサートも気に入っている。
こちらはかなり自由度高いし。
>>37
>あ,返り値の一時変数に代入するような意味のない記述を
ごめん、意味がわからない。
↓みたいな意味なんだったら const なくてもエラーが出るが?

int getlval(void);
getlval() = 3;
std::string f();
f() = f();

int const * const * const * const * const * const * const * const * const
>>41
ナニコレ(つД`)キモイヨー
謎々ですか?
>>41
しかしこれも正当な型なんだよな.
まぁ,こんなのを実際のコードで見た日には食ったメシも吐いちまうが
ツリー構造とか作ると時々出来るね、それでもさすがに int **** ... は無いか(笑
>>45
時々も出来るかヴォケ。
漏前はツリーの深さを最初から決め打ちにするのかと小一(ry
unionでも勉強しろ。
47デフォルトの名無しさん:04/03/04 20:28
そうなの?
const の型やら、単にバカみたいに間接アクセスなポインターはまだ追いやすいよ
メンバ関数ポインタだの、配列を返す関数だののプロトタイプはショック死しそうだ。
それよりもキツイのが boost::lambda とかのプログラムから自働生成される型とかタイプリストとか
C++はconstメンバ関数があるところがいいよね。
そういうときにふとmutableの存在を思い出したりもするし。
>48
配列を返す関数はダメなの?
vectorやbasic_stringを返す関数はどう?
51const至上主義:04/03/06 17:06
const の const は〜♪
みんな const だ〜♪
世界に広げよう〜♪
const の輪〜♪
52デフォルトの名無しさん:04/03/06 23:49
C++のconst好きだったんだが。
ポインタを渡したり、参照を返す関数書いたりするようなときな。

ふと気づいたら、JavaとかC#とか、C++の後に出た言語は、
全て上で書いたようなconstが無くなってたのはショックだった。

どうして、無くなったのかだれか説明してください
馬鹿に配慮したから。
Delにはあるよ
55s:04/03/07 03:14
const復権運動を…ゲフンゲフン
finalがあるよ
57s:04/03/07 03:22
うぉこんな時間にレスが.
ちなみにJavaのfinalなら使えないよ...
>>57
何で?
あ、Javaだと参照型のフィールドとかは変えられちゃうってこと?
6052:04/03/07 03:54
>>58

finalは変数が初期化された後更新されないことを保証する機能で、
変数が指すオブジェクトが更新されないことは保証しないから。

class Bar;
class Foo {
 private: Bar mObj1;
 public: Bar & Obj1() const {
  return mObj1;
 };
}

みたいのと等価なコードはfinalでは書けないでしょ。

ここでポイントは、
・mObj1がFooの利用者から全く更新されないことを保証できること
・publicなメンバ変数と同様にObj1()がmObj1を指していること
・Fooの内部からはmObj1を好き勝手に変更できること
かな。

って良く考えると、これもいろいろと抜けがあるなぁ。
Obj1()のポインタをとればmemcpyとか使って更新できるし、
どっか他で捕まえておかれる可能性を考えればFooの内部であんまり好き勝手
できないだろうし・・・

もしかしてこういう可能性を考えると、constが無意味になるから無くしたとか・・・
コンパイル通らない...
const Bar & Obj1(){ ですか?
62s:04/03/07 05:40
>>61
そういうことさね.>>60
>Obj1()のポインタをとればmemcpyとか使って更新できるし
というのは嘘.

つまり>>61のように,const Bar& Obj1() とやれば,
ポインタ取るときもconst*しか取れないのだ.
const_castしないとmemcpyで書き込めない.

∴const最高.
でもうっかり書き忘れると痛いときもある.STL使ってる時,特に…
Javaで導入されなかったのはまぁ許すとして,
Dに導入されなかったのはちょっといやだ.
6360:04/03/07 18:23
色々ウソ書いてますね。すんません。

そもそも自分の疑問は、どうしてconstが無くなった言語が多いのか
ってことなんですが。
C++のconstの有害性みたいのを、ぐぐったりしてるんですが、
納得のいく理由が見つかりません。自分は上で間違いを色々書いたわけで、
そういう誤りを減らすためとか言われると、それまでですが。

やっぱり「馬鹿に配慮したから。」なのかなあ・・・
>>63
ttp://www.digitalmars.com/drn-bin/wwwnews?D/15187
ここ一通り読んでみると面黒い鴨よ。
>>64

> 1) Too complicated (look at all the wierd rules and perterbations it causes
> with template specialization and overloading).
> 2) Too confusing.
> 3) Insufficient utility.
> 4) Optimizers can't reliably use the info anyway.
> 5) Ugly.

一言で言うと、書いた人以外には解りにくいコードになるってことですかね?
66s:04/03/07 22:06
>>64 thx!!
むしろ書き換えるな!という意味で解りやすいと思うんだけどなぁ
Javaで >>60-61のようなやつだと、
class Foo{
  private Bar mObj1 = new Bar();
  Bar Obj1(){
   return mObj1;
 }
}
こんな感じ?
でも、ポインタのないJavaだと、
外からFoo内のmObj1の参照先を変えられなくないですか?
foo.Obj1.x = 20
みたいのを禁止したいって話です
なるほど。やられてしまいますね。
71s:04/03/08 00:15
むしろ,

・関数の引数はデフォルトでconst参照,
・メンバ関数はデフォルトでconstメンバ関数,

…などとするのはどうか.
constとは逆の, "mutable" とゆうキーワードを導入して.

…あれ?
解りにくいとか言われたら、もうそこで試合終了なんじゃないか?
どう形を変えても。

うかつにオブジェクトの参照を渡せないっていうのも困りものって気はする
わけだが。
7360:04/03/08 01:46
>>64-65
ありがとうございます。なんとなく斜め読みしました。
const廃止が納得できました。

コンパイラ作るのがだるいとか最適化の問題は、自分の興味からは外れるので置いておいて。
const付いてると使いにくいって言うのは、プログラマの質の問題だから置いておいて。

type modifierという発想自体、uglyなものというのが納得できました。

読み取り専用にしたかったら、専用のInterfaceを用意するのが、smartな解決法ですね。
#実際にやるとなると、死ぬほど面倒そうですが・・・

例えば関数のパラメータなんかで、constにして渡したい場合なんかは別ですが、
これもtype modifierとして読み取り専用を保証するのではなく、DBCの様な概念で不変表明として表現する方が、
確かに高機能で且つ一貫性もあり良いんですね。
(まあ、Dにはin,out,inoutで引数を修飾する機能がありますが)

↑こんな理解にたどり着きました。
おかしいところ多々あると思いますので、よろしければご指摘ください。

#でも、constは便利なんだよなぁ・・・
>type modifierという発想自体、uglyなものというのが納得できました。
>読み取り専用にしたかったら、専用のInterfaceを用意するのが、smartな解決法ですね。

俺は const は constのT型を自動的に生成してくれる機能だと思ってるのだが…。
つまり type modifier ではなく、読み取り専用の interface をもった型を自動生成してくれるのが const じゃないのか?
const をつける事、要するに読み取り専用にする事の目的は、コーディングミスの防止なわけですが、
ところで const をつけようがつけまいが、動作は変わらない。
だから読む側(動作を理解する側)からすれば、無いほうが読みやすいに決まっている。
そこで読みやすさを求めれば const を取り除くのは、目的を達成しているから正しいが、
それと同時にプログラムの信頼性を捨てているというのが問題。
const にあたる機能は絶対に必要と思うんですが、const は型にすべきでは無いには賛成。
D の取った方針は片端だと思う。
> だから読む側(動作を理解する側)からすれば、無いほうが読みやすいに決まっている。

ローカル変数の const はコードを明解にしてくれることが多いと思っている。
初心者のよくやる変数の使いまわしも起こり得ないし、
値に対する名前のふさわしさも、初期化さえ確認すればあとは信頼できることになる。
7773:04/03/09 01:43
>>74

読み取り専用のinterfaceを自動生成する機能を追加することで、
type systemが破綻をきたすんじゃないかという懸念で、
最近の言語はconstを捨てたのかな、
と考えたわけです。

いまいち自分でもこの辺の理屈がよくわからないので、もう少し考えてみます。

>>75

constは型にすべきではないならば、どういう方法になるのでしょうか?
表明として表現しておいて、その表明をチェックする賢いコンパイラを作るのが良いのか、
あるいはもっと別の方法をお考えなのか。。。

よろしければお聞かせください。

#べつに言語を作りたいわけじゃないんですけどね・・・
俺的にはポインタも型なんだけど、逝った方がいい?
>>78
いや、ふつうだろ。
80デフォルトの名無しさん:04/03/09 19:48
>>78
ポインタ型って言わないか?普通
言うよね…
よかった、俺だけじゃなくって
82デフォルトの名無しさん:04/03/09 20:27
キャストやtypedefの元に使える以上、型であることは確か。
オブジェクトをconstにするとconstメンバ関数以外は呼び出せなくなる

ってことは全部のメンバ関数にconstをいちいち付けないといけないの?
オブジェクトを非constにする場合も考えて非const版の全く同じ関数も書くの?
随分ねんどくさいんだね
const は型を修飾する型だけど、ポインタは本質的に別の型定義だよ。
>>83
書くとき面倒かデバッグするとき面倒かで決めなさいって事
>>83
非constオブジェクトからconstメンバ関数は呼べる。
ただ、例えば、
「constイタレータを返すconstメンバ関数」
「非constイタレータを返す非constメンバ関数」
を両方用意しないといけないのは確かに面倒かも。
>>83
constのインスタンスに対しても呼び出したいメンバ関数は全部constを付ける。
当然メンバ変数の変更はできなくなる(mutable以外)が、
それは考えてみればあたりまえでしょう?

constの時と非constの時でどうしても振る舞いを変えたい時だけ
const版と非const版を別に用意する。

実際、クラスの設計が破綻してなければ、ほとんどの場合は別に用意する必要はないと思われ。
クラスメンバを直に参照可能にするよか、
クラスの参照を直接返してもらうインライン関数を多数用意したほうが
その後の拡張なんか考えても理にかなってることって多いと思うんだけど、
そうなると大抵、同名の const 関数と 非const 関数がズラズラ並ぶことになるな。

メソッドとしての性格がはっきり読み取れるようになるので、
俺としては逆に好みのスタイルなんだけど…。
89デフォルトの名無しさん:04/03/11 01:37
>>クラスメンバを直に参照可能にするよか、

これだけでもかなりハァ?な感じだが、

>>クラスの参照を直接返してもらうインライン関数を多数用意したほうが

これも、メンバの参照を直接返すってコトか?
そんな実装を直接晒すクラス設計はお話にならん。
実装の詳細が変わったらクライアントコードみんなあぼーんか。めでたいな。
>>89
ちょっと感動した。
そのとーりだな・・・反省
おまえら、constも美味しいけど、typedef enum も大層珍味ですよ!
この二つだけでどんぶり飯4杯は軽いです。
92デフォルトの名無しさん:04/03/15 23:31
>>91
今時C++でそんなもん使うかな?
const_castでconst厨の防壁を破る
mutableも使ってください。
>>89
クライアントからは関係のない、実装の詳細内で使うような
プリミティブ型やstructに近い性格のクラス(例えばベクトルクラス)
なんかではありだと思うけどな。
vec.x() = 0.1f;
みたいな感じで。

個人的には、アクセサなのかマニピュレータなのか分かりづらいから
好きではないけど、publicのメンバに比べたら、assertしかけたり例外投げる
余地がある分マシじゃない?

>>94
逆に、どういう時に使うの?
ハンドルとかのクラスの状態変数に使ったことがあるくらいだなぁ。
第33話「コンスト強襲」
>>95
mutable は、外側から見たクラスの挙動を変えずに、コードの性能を改善するための最終兵器…かな?

例えば、線形の検索が頻発するリストがあったとして、直前の検索結果を
次の検索の高速化のためのキーに使えそうなら、おもむろにメンバに
mutable int _index;
とかを追加して、次回の検索に役立てると。

普通この手の話は、アルゴリズム自体を改善しろよとか、
使えそうなキーがあるなら外部からも取得できるようにして
呼び出し側が指定できるようにしろよとか、そんな腐った設計の仕事に
関わりあいたくないとか言われてしまえば、そこでお終いになるわけだが、
あまり考えたくない諸般の事情…

・何らかの(政治的含む)事情により、他のコードに手を出すわけにいかない
・もう時間が残っておらず、大きな改修をくれている暇が無い
・このクラス単体の性能が上ることで、誰も不利益を被らない

なんかによって八方塞りなんだけど、なんとか目標の性能を達成したい時とかには、重宝したりしなかったりします。

あとの使い道は…参照カウンタ類とか。
これはデバッグビルド時、あまりリッチな開発環境を使えなかったり、プロファイラなんかが
役に立たない時に、やはり外側の挙動を変えずに、ナニが何回呼ばれて何秒使ってるとか
局所的なチェックを入れたい時に、役に立ったり立たなかったり。

const 参照しか返してないのに、明らかに非constメソッドに接触されていて、
どこが原因か追っかけ倒したら>>93が悪の華を咲かせてたりとか、そういう事態に対する
自衛手段になることもあったりなかったり。

自制して使えば、それなりに出番も持たせられる、そこそこ便利な機能だと思うよ。
C++のこういう泥臭くって現実主義的なところ、俺は好きです。
>>97
俺は嫌いです。

デバッグビルド時に論理的にちゃんと動いているかチェックする目的以外で
mutable は使わない/使わせない。

特に
・何らかの(政治的含む)事情により、他のコードに手を出すわけにいかない
・もう時間が残っておらず、大きな改修をくれている暇が無い
これは最低だろ。
政治的理由の場合はラッパーで包んだり、馬鹿避けの仲介オブジェクトを挿んだりして
なんとかするのが唯一のまともな解法だと思う。
時間が残っていないのはもうどうしようもないけど、
予防策はユニットテストだろうか。

・このクラス単体の性能が上ることで、誰も不利益を被らない
これ意味わかんない。
俺は>>97でではないが…。

>>98
>予防策はユニットテストだろうか。
なぜ?
>・このクラス単体の性能が上ることで、誰も不利益を被らない
>これ意味わかんない。
なぜ??

お前、"デザパタ"だの"XP"だのと並べ立てて他人を非難する
某言語厨とそっくりだぞ。
mutableは積極評価に良く使うなぁ.
大きな数値のコンテナで数値の平均を保持する変数をmutableで,とか.
その数値が有効かどうかのmutable boolとセットで.
10198:04/03/16 14:34
http://www.geocities.co.jp/Milano-Cat/1568/throw.swf?b64=DYLNgsGCq4LojL6CwYLE%0Dl3aC54LIgqI%3D%0DDQ0NbXV0YWJsZQ%3D%3D

>>99
まあキミが97ではないという事にしておいてあげるけど

クラス単体の性能が上ることで、誰も不利益を被らないクラスのメンバは
mutable キーワードを使ってよい。

って意味わかんないんですけど。
mutable って const_cast と同じ種類の危険性をはらんでるってわかってるかな?

>>予防策はユニットテストだろうか。
>なぜ?
#もう時間が残っておらず、大きな改修をくれている暇が無い
なら、大きな改修をする必要性がなくなればいいわけで、
ユニットテストは(その効能が事実であるならば)有効でしょう。

102100:04/03/16 14:39
というかむしろmutableは必須の言語要素だと思うよ.
C++のconstは「bitが変更されない」,という意味のkeywordで,
これはしばしば「objectが変更されない」というsemanticsと異なるときがある.
この差異を吸収する機構としてmutableがある,と漏れは思っていたんだけど.
10398:04/03/16 14:40
書き忘れたけどさ

>>99
>お前、"デザパタ"だの"XP"だのと並べ立てて他人を非難する
>某言語厨とそっくりだぞ。

某言語厨が何故C++使いを叩くのかわからなかったけど、
俺が叩かれてたわけじゃなかったんだとわかったよ。

デザパタもXPも有効なら覚えればいい、使えばいい。
自分が理解できた事以外はみんな有害って事にしちゃう君は
未だに構造化とか言いながらグローバル変数を肯定してる
某言語厨とそっくりだぞ。
10498:04/03/16 14:45
>>102
>C++のconstは「bitが変更されない」,という意味のkeywordで,
>これはしばしば「objectが変更されない」というsemanticsと異なるときがある.
あなたの>>100での例で言えば、
クラスの責任と役割を分割しきれていないんじゃないかと思う。
平均値が必要なら、専用のクラスに別ければいいじゃない。
コンテナが平均値数える必要はないと思うんだけど。

mutable はどうしようもない矛盾を解決するための手段だと思うけど、
mutableを乱用する人は、解決可能な矛盾までうやむやにしていると思う。
>104
100の例はあまり適当ではないですね.
100の例は,数値の平均を取る操作をobjectにまで引き上げるかどうかは
議論の余地が大いにありますし.
ただ,objectに引き上げる場合も数値コンテナが変更されるたびに
平均値オブジェクトに変更を通知しなければならず,データの一貫性という点で
弱点をはらんでいるとは思います.
10698:04/03/16 15:13
>>105
>データの一貫性という点で弱点をはらんでいる
別にデータが重複しているわけではないのだから、
バグなら潰すのみ。
マルチスレッドにおける問題ならば、内包していようが外に出ていようが
そこに問題があるのは一緒だと思うけど。
107デフォルトの名無しさん:04/03/16 15:31
最近、C++を勉強している元Java厨だけど、const いいね。

getterメソッド呼ばれるたびに、clone するの、激しくマンドクセーし。
new とか clone って遅いらしいので、精神衛生上にも良くない。
>>98
"俺は>>97でではないが…。"
なんてバレバレな書き込みする自作自演がいるかっつうの。

何であの文脈で
>・このクラス単体の性能が上ることで、誰も不利益を被らない

>クラス単体の性能が上ることで、誰も不利益を被らないクラスのメンバは
>mutable キーワードを使ってよい。
と読むんだ。>>97が書きたかったのは
・(キャッシュ等の目的でmutableメンバを追加して、)クラス単体の性能が
 上がることで、誰も不利益を被らない。(なぜならそういったメンバは
 privateなことが殆どだからカプセル化を破ったわけではない。)
って事じゃないの。日本語大丈夫?

>>97
>呼び出し側が指定できるようにしろよとか、そんな腐った設計の仕事に
>関わりあいたくないとか言われてしまえば、そこでお終いになるわけだが、
>あまり考えたくない諸般の事情…
ってことわっているにも関わらず、
>#もう時間が残っておらず、大きな改修をくれている暇が無い
>なら、大きな改修をする必要性がなくなればいいわけで、
>ユニットテストは(その効能が事実であるならば)有効でしょう。
なんて事を意気揚揚と書き込んだわけね。
そういうところが某言語厨ぽい。
109100:04/03/16 16:04
>>106
うーん,具体的にどうやれば安全にmutableを排除できるのかちょっと思いつかない・・・
自分のやりたいことは下なんですが・・・

class Data
{
vector<double> v;
mutable double avg_cache;
mutable bool is_avg_cached; // vが変更されればfalseに
double getAverage() const{
if(is_avg_cached){
return avg_cache;
}else{
double result;
// まともに計算;
avg_cache = result; is_avg_cached = true; return result;
}
}
…すごく妥当な使用例だな。
教科書に載せたいくらいだ。
11198:04/03/16 18:13
>>109
class Data
{
vector<double> v;
DataObserver* pObserver;
};

class DataObserver
{
void OnChange();
};
11298:04/03/16 18:15
>>108
http://dictionary.goo.ne.jp/search.php?MT=%CD%BD%CB%C9%BA%F6&kind=&mode=0&jn.x=50&jn.y=13

キミ、日本語もだけど頭大丈夫?
本人気づいてないのかもしれないけど、
自作自演って案外みえみえだよ。
11395:04/03/16 18:31
個人的にmutableはキャスト並に必要悪だと思ってるので、indexや
キャッシュの例の場合には、まず使わないかな。

>>109の様な場合なら、>>111の方を取るかな。
俺はpimplで遅延評価(必要になったらディスクから読み込み)の時にmutable使ったな。
115100:04/03/16 19:24
>>111
なるほど.一括したobserverへ投げるのですね.
確かにそのほうが拡張性と柔軟性がありますね.
参考になります.
11698:04/03/16 19:46
>>114
具体的には何のためにmutableにしたんでしょうか?
constのオブジェクトに非constのimplへのポインタを持たせたい?
11798:04/03/16 19:54
>>114
const性について誤解しているのかなと思ったので
参考にだけど、下記はコンパイル通るよ。

struct InformationImpl
{
StringType GetName();
};

struct Information
{
InformationImpl* pImpl;

Information(){}

StringType GetName() const
{
pImpl->GetName();
}
};

int main()
{
const Information info;

info.GetName();

return 0;
}
11898:04/03/16 20:01
例えが良くなかったかも。setterがいいね。
typedef char* String; // ご愛嬌

struct InformationImpl
{
void SetName(String name); // unconst method
};

struct Information
{
InformationImpl* pImpl;

Information(){}

void SetName(String name) const
{
pImpl->SetName(name);
}
};

int main()
{
String name;
const Information info;

info.SetName(name);

return 0;
}
119114:04/03/16 20:23
pimplと書いた(ちょっと違う)から誤解があるのかもしれないけど
委譲している実装部(というかデータ)部分は初期値でNULLが入ってるんだよ。
そして、必要なアクセスが実際に発生したらnewする。

こんな実装にしたのは、特に起動時に待たされる時間が長かったから。
#実際には、優先度を下げたworkerスレッドでの読み込みを併用したけどね。

別にこのやり方が正しいとも、エレガントだとも思わない。
ただ、俺が実際に使ったというだけのこと。
120114:04/03/16 20:28
だらだらと関係ないあたりまえのコードを書いてもらってるから、俺も書いておく。

class A {
 class A_impl;
 mutable A_impl *p;
public:
 A(): p(NULL) {}
 void access() const;
};
void A::A_impl::access()
{
 ...
}
void A::access() const
{
 if (!p)
  p = new A_impl();
 p->access();
}
12198:04/03/16 20:43
>>119
一般にはそれはpimplではなくてproxyと呼ぶけど、
それで何故mutableが必要なの?
122デフォルトの名無しさん:04/03/16 20:58
晒age
12395:04/03/16 21:02
>>121
mutableでないと、constメソッド内でpにnewした
アドレスを代入できない。

ってそういうことじゃなくって?
動作としてはproxyかもしれないけど
普通、proxyってのは目的のクラスがあって、直接アクセスする代わりに
それに対してのラッパー的なものを用意する、主と従が逆の意味な気がするけど。

形だけでパターンを分類している人にはどうでもいいけどね。
12599:04/03/16 23:35
>>98
おまえは本当にmutableを理解しているのか?
12695:04/03/17 04:43
しかしmutableと書くとどうしてもmutexを連想してしまうな。
#define volatile mutex

mutex mutable int a;

なんて書き方想像すると嫌な感じ・・
127126:04/03/17 04:44
失礼。
#define mutex volatile
ね。
>>109に対する、
>>111以降のコードって、あんまり価値がない。

>>109の例では
「平均値の取得によって、オブジェクトの状態が変化しない」
ということが表現されていましたが、

>>118では、
「名前の設定により、オブジェクトの状態が変化しない」
という、"意味的に"不適切な表現がされているとおもいます。
まあ、"意味的な"オブジェクトの状態の変化と
実際のオブジェクトの状態の変化を切り離す事が出来る
と言う例のつもりなのでしょうけど。

>>124
> 主と従が逆の意味な気がするけど。
ぜんぜん逆には思えませんが。
起動時に目的のクラスにアクセスすると待たされる時間が長かったからwrapしたんでしょ?
12998:04/03/17 08:29
>>123
なんでconstメソッド内でメンバに代入する必要があるのか?
もうここまでくると何故mutableキーワードを使う必要があるのかと
同義になっちゃってるんですが、何故使う必要があるのか、
それを聞いてるんですが。

>>124
GoF本のproxyの適用可能性の項を読め。
聞きかじりの知識だけでパターンを脳内分類している人は知らなかっただろうけどね。

>>125 = >>123 = >>95
キミはmutable以前にconstを理解できてるかな?
あわれな自演君、キミね、知識不足だから自作自演ばれてるって言ってるのも
理解できないのかな?
キミが説明しているのは mutable キーワードの機能なのね、
滅多に使う必要のない mutable キーワードを使うべきまっとうな理由を聞いてるんだよ。
13098:04/03/17 08:34
カッとなったから冷静に考える事を忘れてました。

馬鹿が2匹いる可能性もありますね。
>>125
ごめんね。
131デフォルトの名無しさん:04/03/17 08:41
>>98 から↓の24と同じニオイがする。
http://pc2.2ch.net/tech/kako/1056/10567/1056716338.html
13298:04/03/17 08:44
>>128
>「名前の設定により、オブジェクトの状態が変化しない」
>という、"意味的に"不適切な表現がされているとおもいます。

誤解されているようですが、>>118
constのオブジェクトが非constのオブジェクトへのポインタを持つ例です。
constのポインタとconstオブジェクトへのポインタを混同してないか?を
確認する為に掲示したもので、>>109に対応するコードとして掲示したのは>>111のみです。

13395:04/03/17 08:58
>>129
何で自作自演になるの?
自分のスタンスは>>113で言った通りだが。

>もうここまでくると何故mutableキーワードを使う必要があるのかと
>同義になっちゃってるんですが、何故使う必要があるのか、
>それを聞いてるんですが。

は、俺が聞きたいくらいだ。
もともと95で投げた発言は
>逆に、どういう時に使うの?
だぞ?

分かってるとは思うが・・・くらいは>>123で書いておけばよかったか?
13498:04/03/17 08:59
>>131
キミ、悪いけどキショイよ。
虐めた人がいたスレッドは全部取ってあるの?
それで嫌な事があるたびに「同じニオイがする」とか書いてるのかな?


本当に、病院、行った方がいいよ。

13598:04/03/17 09:01
>>133
レス番号見間違えてた。
スミマセン。
なんだかなあ
底が知れちゃったからもういい、勝手にどうぞって感じ
Effective C++本では、つかえるところにはconstをどんどん使おうと
啓蒙してますが、そういうものなんですか そうですか。
アンチパターンならぬアンチコンストパターンみたいなのが必要なんだと思う。
C++ の開発者(名前忘れた)が言っていたけれど、 private にすべきでないメンバまで private にしてしまい
再利用が難しくなる問題があるが、これを上手く解決する良い方法が現状ないといってました。
const も同様の問題を抱えているとは思う。
そこまで大げさな話なのか…。

クラス提供側の想定してないレベルに再利用性を求めるなら、
自己責任でconst_castしろやの一言って気がするんだが、
気に食わない人、いっぱいいるんだろうなあ。
>>134がキモすぎる。
この人病院行ったほうがいいよマジで。
みんなで病院へ行きましょう
まあ、きょうびconstだけで飯が三杯食えるような奴は
まとめて病院逝った方がいいのかもしれんが(w


…その病院で出される飯の内容に興味があるなあ。
あと、隣の病室から「こんな飯食えるかー!!」
ガシャーンバリーンとか聞こえてきそう(w


もちろん漏れは良い子ちゃんだから、出されたご飯は何でも残さず食べまつよ?
カレー味のうんこでも、うんこ味のカレーでも。
const味のmutableや、mutable味のconstが食えますか?
やぱり、スカな人は脳内で

const_cast<排泄物 *>(うんこ)

なことしてるんだろうか?
>>139
関数オブジェクトとかを使い始めると、結構厄介ですよ
const を取り除いた型の抽出は、boost とか使えばまぁ簡単にできますけど
ちょっと強烈だと思う。
ちなみに個人的には const 肯定派です。
ただ上手に使うのは結構難しいとは思う。
constを使っちゃいけないのにconstにしちゃってるソースって
あんまり見たことないけど、
やっぱり>>118みたいなソースを書く人もいるし。
147デフォルトの名無しさん:04/03/17 22:22
ローカルなオブジェクトをconst宣言しちゃいますか?
たとえば
const int s = v.getSize();
for( int i = 0; i < s; i++ )
v.get(i).clear();
みたいに。
148
>>147
変えちゃいけないなら当然しちゃいますよ。
constといえば、
クラス内定数として,
static const int INT_ZERO = 0;
な感じで初期化できればいいのになぁ。
結局面倒だからdefineで切ってしまう。

Javaだとできるんだっけ?
あれ?それって標準では許されているのでは?
後,コンパイラがその記法に未対応でコケる場合は
enumハックと呼ばれるものが常套手段になってますよ.
>>150
確かにできるけど、バイトコードがえげつない増え方したりして微妙に恐怖をそそる。

C++なら、int で済む限りは、そこはenumだろうね。
#define 使っちゃったら、スコープがヘッダ単位になってしまう。

本来列挙子であるところの enum で定数定義するのは無作法呼ばわりされかねないけど、
スコープはクラス内で決着するし、クラス内定数としての使い勝手は悪くないよ。
C++の建前としては、intサイズであるのも保証されてるそうだし。
守ってくれない(最適化等で勝手にcharサイズにしちゃったりとかする)コンパイラも多くって、
本当に仕様なんだろうかと思うことも多いけど。
>>151
ああ、ほんとだ、試してみたらVC7.1だと出来るのね。
知らなかった。
仕事上、特殊なSDKを使ってるので、未だにVC6がメインなので。

うーん、enumハックはtemplateでもよく使う
手法なんで知ってますが、組んでるプログラムの
関係上、どちらかというとfloat定数が欲しい場合が
多いので。

>>152
スコープ外れると知りつつも、スコープあまり関係ない定数の場合は
打鍵数の少ない方を取ってしまうダメ人間。
もちろんほんとにスコープで分けたい場合はメンバにしてますけど。
>>151の機能は標準化したの比較的最近だよな、そういえば。
確かに環境によっては使えないわ。
floatの定数欲しいときには困るんだよな…。
155デフォルトの名無しさん:04/03/18 04:34
const_cast 最強
>>154
VC6以外のコンパイラは昔からほとんどできた
ただVC6の勢力が大きかっただけで。
まるでリトルエンディアンのアーキテクチャと
ビッグエンディアンのアーキテクチャみたい。
ところでモマイら、関数引数にconst付けますか?
int func(const int arg1, double *const arg2) {...
みたいな感じで。
つけるよー。
つけまくり。
ソースとデステネーション区別する意味でも、参照しかしない引数は
基本型以外ぜーんぶconstつけ。

…みんなそうだよね?
>>157
const int は意味がないので使わないが
const int& は使う。
160157:04/03/18 16:50
>>159
const int &を使うのは常識として、const intを使うかどうか聞きたかったんだが…
つまり、>>147の例でconstをつけるなら、
関数引数にも(誤って代入しないように)constをつけるのもいいかな、と思うんだけど。
>>160
関数引数に代入云々は、呼び出し側には全く関係ないからなあ。
呼び出し側から見てどうでもいいものをプロトタイプに反映させるのは
個人的にはあまり好きくない。
>>161
必ずしもプロトタイプに反映させなきゃならんわけでもないぞ。
>>157の例なら、
int func(int arg1, double *arg2);
と宣言しておいて、定義側では>>157のようにすれば良い。

inlineやtemplateなんかには使えんがな。
宣言と定義が食い違うのは気持ち悪くないか?
気持ち悪い悪くない以前の問題で、定義と宣言の関係が崩壊してるんじゃないかと小一時間
ていうか、それって普通にコンパイラに怒られないのか?
>>164
それは無問題。
試してみろよ。
試してみろじゃなくて、規格で保証されているのか?
どっちにしろ、俺も気持ち悪くて使う気にはならんが。
いくらプロトタイプ宣言がコンパイラのためのものとはいえ
通ればいいってもんじゃ無い気が…


ていうか、本当に通るの?
マジで??

なんか今まで信じてたものが崩壊してく感じなんですが。
次世代言語EC++ではmutableは廃止されます。

http://www.caravan.net/ec2plus_j/language_spec.html
通る。規格でも合法。
>>169
規格の話するならできれば引用して欲しい。

>8.3.5 Functions 3
>(略)
> Any cv-qualifier modifying a parameter type is deleted.
> [Example: the type void(*)(const int) becomes void(*)(int) - end example]
> Such cv-qualifiers affect only the definition of the parameter within the body of the function;
> they do not affect the function type.

というわけで完全に合法だな。
でも個人的には宣言と定義で見た目が変わるのは気持ち悪いし、引数が const int なのも
気持ち悪いと思う。
あー、確かにそうだわ。
引数の上の const の有無では、関数のオーバーロードは成立しねえんだ。
関数プロトタイプの引数上 const の有無からじゃ、呼び出し側がどの関数呼べばいいのか
コンパイラは判別つけられないから、こりゃ当然の仕様なのか。

かといって、プロトタイプと実関数の定義が分かれてしまってて許されるなんて…。
気持ち悪いよ〜!!
>>158
> 参照しかしない引数は
> 基本型以外ぜーんぶconstつけ。
ポインタで渡したり参照で渡したり以外という意味でつか?
>>168
mutable指定子
例外処理
実行時型識別
ネームスペース
テンプレート
多重継承と仮想継承

mutable以外は外しちゃならない機能ばかり。
組み込みC++って大変ね。
例外ダメなのか…

RTTIはまあいいとして…

namespaceもなんとか大目に見られるとして…

テンプレートはコンパイラ側の問題だろうに…
上でも誰かが言ってたが、インラインアセンブラとの相性いいんだぞ…

多重継承はまあいらんとしても、仮想継承禁止ってなんだそりゃ…



C++なのか、それ。
C99と何が違うんだ。
多重継承を使わないなら、仮想継承も要らないんでないの?
>>175
C++使いも最近は実装の多重継承しないのが本流になっているので、
>>174がインターフェイスクラスの継承も機能的には多重継承だと気づかなかったに
8086ガバス
177174:04/03/19 19:28
>>176
R4300ガバス進呈。
近所のTSUTAYAでGBAと交換できまつよー。



鬱山車納。
組み込みC++でうんざりするのはstdネームスペースがないことだよ。
ま、標準ライブラリも無いに等しいくらい少ないのだが。

なまけものコンパイラ屋が考えたのだと思ってる。
>>178
stdネームスペースが無い…マジスカ?
標準ライブラリも無いに等しい…マジスカ?

規格として存在する意義がよくわからん…。
とりあえず最底辺だけ決めたってことなんだろうか。
>>179
>規格として存在する意義がよくわからん…。
禿道。

規格を作ってポータビリティを向上できるようなシステムはリソースもあるので普通のC++でいいと思うし、
リソース的に色々制約があるシステムの場合はターゲットごとに癖が強いから規格にする意味がないし。
181デフォルトの名無しさん:04/03/25 01:43
javaにもconstがほしい。
void fund(const Object &obj) const;
のconst ね

行って帰ってきたら、中身がかわってるかどうか、
わかんないなんて...
182デフォルトの名無しさん:04/03/25 09:35
読み込み専用の(ゲッターだけの)インタフェースを実装し、
そのインスタンスを渡すようにしてはいかがだろう。


&って?
>>182が言った様なアプローチを基本にするために、constを
取っ払ってるのが最近の流行なんだろうけど…。

そのために一々細かくクラス用意するのはバカらしく思えることだってあるし、
J2MEとかだと、そもそもそんなことのためにクラス用意してる余裕は無かったりするんだよな。

基本型の配列渡すのにも、一々どっちがsourceでどっちがdestinationか確認しながらやるのはビクビクもんだ。
コンパイラにちょっと叱ってもらうだけでも、ヒューマンエラーは随分減るのに…。
184遅レス:04/03/30 02:13
>>16
foo()はメンバ変数を変更しないという意味だろ?
185デフォルトの名無しさん:04/04/03 12:09
getter で、変更されてもいい値を返すってことは、
clone なり new なりが発生するってことだろ。

clone と new が早けりゃ文句ないんだよ。
java は clone と new が遅いだろ。
186デフォルトの名無しさん:04/04/10 04:36
constってC言語に属する低級なもので、本物のOOP言語には必要ないんだと思う。
「本物」ねぇ・・・
188デフォルトの名無しさん:04/04/10 08:58
本物のオブジェクト指向言語は、型の変更不能性をインターフェイスで表明する。

public void change(Object argObject) { /* ... */ }
public void unchange(ConstObject argConstObject) { /* ... */ }

さらに、引数への代入をコンパイルエラーとして報告してもらいたければ、

public void unchange(final ConstObject argConstObject) { /* ... */ }

を使う。
関数オーバーロードでまとめてしまうと、OOPもへったくれもないってことなのか

道理だが…
まったく使う気しねえなあ…
理想と現実の間には深い溝がある.
>>188
class ConstBase {}
class MutableBase extends ConstBase {}
class ConstSub extends ConstBase {}
class MutableSub extends *** {}

*** はどうするのよ?
192デフォルトの名無しさん:04/04/10 22:47
>>191
多重継承の呪縛に囚われた人間がここにも……!?








その腐った設計を見直せ
いや、だから const は継承では賄えないと言いたかったんだが。
>>192
はずかしい
>>192
えっち。
>>192
Java厨ウザイ
>>192
ちんこ洗ったか?
198s:04/04/13 05:22
突き詰めて逝くとHaskellやCleanとかの副作用のない関数型言語を使えばいい,と思うに至った.
勉強中.

199デフォルトの名無しさん:04/04/14 23:31
やっぱmainはこーだよな

int main(const int argc, const char* const* const argv)
やーめーれー
コンパイラにチェックしてほしいだけとちゃうんかと、小一時間(ry
引数自体のconstは好きにしてくれって気がするな。
有体に言うとウザい。
>>199
コーヒーこぼしちまったじゃねーかw!!
>199
だな
これはできんのだな
int main(int argc, char **argv) {
{
const int argc = argc;
const char*const*const argv = argv;
return 0;
}
}
199も厳密には規格違反のような希ガス
const int main(const int argc, const char* const* const argv) const
mainにthisがあると、君は!
void func (void) const { ... }
          ↑このconstってCで合法だっけ?
非合法。
すなわち危険な匂いを漂わせる船の男にして、港の女はメロメロ。
211デフォルトの名無しさん:04/04/23 18:24
>>209
メンバ関数以外にも使える処理系があるのか?
心配するな。ずっとconstさ
>>209コレさえあれば合法(脱法?)
#define const
エリオット・ネスが
#ifdef const
#error 通報されますた!
#endif
を主要ヘッダに仕掛けてましたよ!
奴は一人でもやる気です!
>>214
#include <hoge>//など
#define const

マジレスするとヘッダのインクルードより後にやればいいだけでは?
>>215
自分の家族を守れば十分なんだろう?
217デフォルトの名無しさん:04/05/08 23:24
218デフォルトの名無しさん:04/05/08 23:36
ポインタにconst忘れる奴多杉なので、
願わくば、後ろにconst置くスタイルが一般的になって欲しい。
219デフォルトの名無しさん:04/05/08 23:47
C++相談室の次スレはここですか?
>>209
亀レスだがfunc 後のfuncはクラスのメンバ関数にのみ許される。
一般の関数については許されてないし、必要ない。
func の後のfunc 罰
func の後のconst 丸
222v(^・^)v:04/05/09 00:48
C++相談室の次スレはこちらです。
http://pc5.2ch.net/test/read.cgi/tech/1084030770/
Java/C#の仕様を見るといかにC++のconstが馬鹿げたものかがよくわかる。
単にあちらさんの教義に染まっただけでしょう。
IBMは何でreadonlyのままにしなかったんだろう
readonlyの方がわかりやすかった気も
素人なんですけど、
constが、ある変数を誤って変更しないようにする目的であるのなら、
constとして扱いたい変数の名称を、コンストっぽいやつ、
例えば、GravitationConstantとか、a_constとかにすれば良いの
ではないでしょうか。
  ハハハ
  ∧_∧  / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 ( ^∀^)<  あほか
 ( つ ⊂ ) \_________
  .)  ) )
 (__)_)

>>226
そこでconst_castですよ
よーしパパ文字列リテラル書き換えちゃうぞー
素人なんですけど、
privateが、あるメンバ変数を隠蔽する目的であるのなら、
privateとして扱いたいメンバ変数の名称を、privateっぽいやつ、
例えば、private_dataとか、a_privateとかにすれば良いの
ではないでしょうか。
そこで #define private public ですよ
>>230
「おい。おまえの作ったクラス、うまく動かないぞ。このprivate_aって変数に0を代入したらおかしくなったぞ。」
と言われないためです。
#define 最強!!!
>>233
bcc
エラー E2153 233.cpp 1: #define 疑似命令には識別子が必要

g++
233.cpp:1:9: macro names must be identifiers

vc
233.cpp(1) : error C3209: '?III' : Unicode 識別子は現在サポートされていません。

mwcc
# File: 233.cpp
# -------------------
# 1: #define I I I
# Error: ^
# identifier expected
ところでWinMainのLPSTR lpszCmdLine
これLPCSTRにするとうまくいかなかったがconst LPSTRだとうまくいった。
typedef CHAR *LPSTR, *PSTR;
typedef const CHAR *LPCSTR, *PCSTR;
だと言うのに。

ところでwindows.hの中の中ではchar*やwchar*から大きく分けて、
〜CHAR/〜CH/〜STRの3種類にtypedefしてるけど、
〜CH系って使っているの見たことない。
const LPSTR = char * const
237235:04/05/23 09:08
>>236
なぬっ!
そういうことだったのか。

winbase.hの中のWinMainの宣言をLPCSTRに書き換えれば、
もちろんうまくいくんだけどそこまでするメリットってないよね。
>>237
「うまくいく」「うまくいかない」が何なのかさっぱりわからない。
>237
何で無理やり const つけるのよ。
もともとついてないんだから変更しても構わないってことでしょ。
自分で変更しないってことを強制したいなら LPCSTR を受ける MyWinMain でも作って
WinMain から呼び出せばどーよ?
240デフォルトの名無しさん:04/05/26 23:55
いたるところにconstをちりばめておけば、「うぬぅ!こいつ出来るな!」と思われるので使いまくってます。
つか、いたるところにconstをちりばめておかないと、「うぬぅ!漏れはここで何をやらかしたんだ!」という思いをしてしまうので使いまくってます。

あれですよ。
ドミノあほほど並べる人が途中に挟むストッパーみたいなもん。
>>241
うぬぅ!解り易い説明だぁ!
>>241
なるほど、どじな同僚に倒されないように、ですな。
>>243
自分で蹴っ倒す事もあるでよ。

まあそのなんだ。
倒さないことが大事なんであって、誰が倒すかは、この際問題じゃないですよ。
>>241
うまい!確かにそんな感じ。
他人の書いたクソ長い関数で
ローカル変数にconstがまったくないとすげえ不安になる

そういうときは、初めて代入するところに宣言をもってって
constにするといろいろ分かってくる。
>>246
コンパイラに「洗い出し」をやらせるんだよな。
漏れも泥臭い仕事の時にはよくやる(w
>>247
Yes. コンパイラは検出ツールでもあると考えているよ。
正直そういうアドバイス機能もあってもいいと思うんだよな。
どうせコンパイラは変数の有効期間を検出してるんだし。

で、
たまに見かけるのが、ループ変数のような一時変数を、関数の先頭で
宣言し、使いまわしている奴。Cのスタイルを引きずってるのかなあ。
明らかにconstractに時間のかかりそうなものなら分からんでもないが、
forループのiが置いてあると書いた奴の能力を疑う。

constからズレたけどオカズっつうことで
>>248
使いまわしの極意は、整数変数にポインタを代入することです。
Cのスタイルを引き摺っているんだろうけど、許せん。
>>249
古くからのプログラマで組み込み畑の人だと、void * の代わりに unsigned int を使ったりするから油断できない。
>>248
>ループ変数のような一時変数を、関数の先頭で

VC++あたりはデフォルトでそれを許してくれないのが…。
>>251
for (int i = ...)
 ...;
for (int i = ...)
 ...;
って書き方ができないことを言ってる? だったらVC.NETにすれば大丈夫。
そうでなくても、大抵の場合は二度目(以降)のintを省略するだけでも違うと思う。
253251:04/05/28 13:35
>>252
あー、それです。
既存のコードの為なのでしょうが、VC.NETでもオプション変えないと
いけないですよね…
昔は最適化がタコだったから
レジスタを使い倒せるように、変数を使い回すのも多少は意味があったけど
今は読みづらくするだけだね。
あ、あの、たまたまここに流れ着いた者なんですが、
246氏付近はどういうことをいっているのでしょうか?
(c++歴があまり長くないので理解できないんだと思います。
9ってコマンドがあって
>>255
何がどう判らないか判らないのだが。
一応>246の話を解説しておくと、怪しげなローカル変数にconstつけてコンパイルすると
エラーがでるから様子がわかるって話だ。
>>254
>レジスタを使い倒せるように、変数を使い回すのも多少は意味があったけど

使い回すよか、中括弧でズタズタにコードを刻んで
変数の寿命を明示的に指定するようにしてた希ガス。
コンパイラ説得スタイルだっけ…最近は楽になったよなあ。
> コンパイラ説得

(アホな)コンパイラ説得ですな。
//Java
SomeObject obj;
{
 int x = hogehoge();
 int y = x * foo() + bar();
 int z = baz(y);

 obj = new SomeObject(x,y,z);
}

中カッコの内部の制御構造がもし複雑になっても,Javaならローカル変数の未代入を
エラーとして報告してくれるので嬉しい.
C++でも出来た気もするけど…

しかしC++ではインスタンスの生成が new 以外でも出来るのでややこしい.
C++で,

SomeObject obj(x,y,z);

などとやりたい場合は,上のJavaの例のようにx,y,zのスコープを
切り分けることができない.悔しい.
なにゆってんのかわかんない
//C++
SomeObject* obj;
{
 int x = hogehoge();
 int y = x * foo() + bar();
 int z = baz(y);

 obj = new SomeObject(x,y,z);
}
本気で何言ってんのかわかんねぇなぁ。
ローカル変数の未代入に警告出すのは言語の機能じゃなくってコンパイラの機能だし、
出せないコンパイラはまず存在しないだろし。

初期化子とインスタンスの寿命を切り分けられないのは…
まあ確かにそうだし、何らかの理由で分けたければ>>262の形になるんだろうが…

あー、あれか。
初期化子になんか使い回しの変数類が紛れ込んじまったりとか、
そういうことを危惧してるのか。
確かにC++は関数の引数の評価順番が不定だから、明示的にこの種の初期化を
やってやる必要が出てくる場合もあるわな。

…正直、それが気になるケースってほとんど出くわしたことないや。
藻前らどーよ。
俺は>>260じゃないけど、そう思うことは結構ある。
>初期化子になんか使い回しの変数類が紛れ込んじまったりとか、
>そういうことを危惧してるのか。
俺の場合は、
int x = hogehoge();
int y = x * foo() + bar();
int z = baz(y);
SomeObject obj(x,y,z);
// ここでまだx,y,zがスコープアウトしていない、ってのが気になる。
// まあ、気になるって言うだけの事だが。
>>264
>>262じゃ不満なの?
266260:04/06/02 08:33
僕が言いたいのは >>264 な感じです.

>// ここでまだx,y,zがスコープアウトしていない、ってのが気になる。
>// まあ、気になるって言うだけの事だが。

(確かに変数の未代入はコンパイラの問題です罠.)
引数の評価順ってのは意図してませんでした…


>>262 は, 自分的に auto_ptrを使ってないのが不満.
あとこのコード片を含む関数が SomeObj* ではなく SomeObj そのものを
返す仕様になっている場合使えない.
>>266

> >>262 は, 自分的に auto_ptrを使ってないのが不満.

そんな枝葉を(w
auto_ptr使えばいいじゃん。この話とは関係ないんだから。

> あとこのコード片を含む関数が SomeObj* ではなく SomeObj そのものを
> 返す仕様になっている場合使えない.

RVOを気にしなくていいなら、スタック上に生成してコピーを返せば問題ないと思うけど。
代入演算子も必要になるけど。
一応コンパイラが冗長代入最適化で消してくれる可能性もあるから
あんまり神経質にならない方がいいんだろうけどね…。
参照カウンタとかが入ってると、多少のオーバーヘッドになる可能性は否定できないが。
スレ違いsage
おい、おまいら!
そろそろconstの使い方まとめてくれ。パーフェクトなやつを。
constだけで一冊本を書いてみるとか
妙に宗教じみた本になるか、
妙に下世話で現実的な本になるか、
下町の人情溢れるハートウォーミングな一冊になるか、
頭から尻尾までみっちりぬるぽの詰まったガガガ本になるか
javaにはconstが無いので不安です。
const に一度慣れ親しむと const のない言語はうんこに見える。
constがあること自体、オブジェクトの寿命という実装側の都合に
近寄りすぎている…というのが新しい世代の言語の言い分だし、それはわかるんだけど、
constでロジック間を信頼関係で結んでいく、あのかっちり感は萌えるんだよなあ…。
const使ってるお陰で最適化がめちゃめちゃ強力に効いた時とか、妙に嬉しいし。
「オブジェクトの寿命」が「実装側の都合」ってどうゆうことだ?
C++ばっかやってる漏れにはさっぱりわからん。
>>274
> const使ってるお陰で最適化がめちゃめちゃ強力に効いた時とか、妙に嬉しいし。
C++でもそんなことありうる?
内部で const_cast やってる可能性もあるし、下手な最適化できないように思うんだけど。
> C++でもそんなことありうる?

ポインタや参照で渡されたオブジェクトはconstであっても
最適化をかけんだろうな。エイリアスの可能性があるし。

作成時からconstになってて、そのポインタを取ってなければ
最適化の余地があるね。

constメンバ関数は最適化の可能性が一番高いような気がする。

つかconstの最大の効能はプログラマを縛ることだと思うよ・・・
イソライソ展開される場合かな
>>274を見て思った。俺もオブジェクトの寿命話はちょっとよくわからんが。
Javaなんかだと設計上状態が変化しない(immutableな)クラスを作成させる。
C++はconstを使うことで一時的に状態が変化しないようにできる。
「状態が変化しない」ことをどの概念で扱うかの違いだよな。
文法が簡単になった分、設計に跳ね返っているのかな?
C99のrestrict修飾子がC++にも早く欲しいな
>>280
restrictって、const/volatileと同列の修辞子?
そうだとしたら、オーバーロードの複雑さが倍になって悶死しそうじゃないか?
>>279
C++ の "const T" ⊆ "T" という直感的な性質がほぼ自動的に得られる
っていうのは便利だけど、Java の、こういった「暗黙知」の様なものを
排除しようという方向性もアリだよね。

設計に跳ね返るといえば跳ね返るわけだけれども、言語上の機能や直感的な
性質を論ぜずに単純にクラスとして分析・定義できる分ラクとも言えるわけだし。
例えば mutable なクラスは(面倒なので)作らないで、簡易な機能だけ実装した
builder の提供でお茶を濁そう、とか。
283279:04/06/09 13:47
>>282
レスありがとう。設計という観点から見て、君の言うように言語に
依存しない汎化もあるな。それにマルチスレッドを意識したりすると
immutableが重要な要素になるのでクラスになっているほうが
わかりやすい気もする。
と、言うより設計側から実装を縛るにはクラスとしてmutableかどうかの
性質付けをするしかないんだよな。
constは実装に近い概念なのだと再認識した。

constが無い環境をやってると、mutableクラスがどんどん減るような
気がする。実装でミスする可能性が高いから設計でカバーしようと
するのだろうか。
>>279
> C++はconstを使うことで一時的に状態が変化しないようにできる。

なんか激しく勘違いしてない ?

volatile const int x; とか書けるのを知らないのか ?

>>277 の最終行が正解だと思うが...。
mutableでは何杯メシが食えますか?
むしろmutableは下剤?
何回トイレに逝けるかな?みたいな?
>>277の最後の行はいわゆる「契約に基づくプログラミング」とかその類ですね。
参照やポインタのパラメータに関しては、変更のあるや無しやがパラメータの型を
見るだけですぐわかるというメリットもある(けど immutable 型でも同じか)。
hoshu
hpshi
const hage
const汚染sage
純関数であることを表明する const って殆ど使われていないと思うんだけど、
なぜなんだろ。漏れも使ってないし・・・

double const power(double x, double y) みたいなやつ。

293デフォルトの名無しさん:04/06/30 18:33
それ、行頭にconst有るのとおんなじでは?
もしやクラスに属してない時は、それが純関数の宣言になるの?

って言うか、純関数ってなんだろう。
純関数って何だ?副作用を持たない関数の事か?
それならconstは何の関係もないと思うが…
誰かの俺規約じゃないの?
漏れの白昼夢だった。
gcc でいう __attribute((const)) が >>292 的シンタックスで、というのを
何かで読んだような気がするんだけど、夢だよね。
関数の戻り値は値渡しだしな
ちなみにこの場合の「純関数」っていうのは、
・副作用が無い
・引数が同じなら、戻り値も同じ
という意味です。
1) constは百害あって一利なし

2) constは諸刃の剣

3) constは神

あなたはどっち?
>>299
3

3択で「どっち?」とは、答えにくいな。
>>299
4) constには大きなメリットがあるが、C++のconstの仕様(特にクラス)は腐っている
mutableマンセー
void const(const const) const throw(const);
>>301
constの大きなメリットを腐らせないためにC++の仕様を改良するとしたら、どうしますか?
面白そうなので、なるべく具体的なのきぼん。
おまいら、スレタイ通りに進んでますね。
>>304
オブジェクトに対するconstは撤廃だろ。
そんなもんのメリットもない。
ついでにオブジェクトの値渡しも撤廃。
ついでにコピーコンストラクタも撤廃。
ついでに参照にNULL突っ込めるように変更。
ついでにオブジェクトの値型変数を撤廃して参照のみにする。
いじょ
>>306
要するにポインタ変数しか存在させない、常にnew/deleteしるってことか。
オブジェクトconstにして防げるバグってあまりなくない?
他のOOPLで開発しててそう感じる。
ReadOnlyなクラスを作るパターンのほうがややこしくなくて便利。
>309
いちいちR/Wなクラスに対応するR/Oクラスを探すのがめんどい。
いちいちクラス設計者の趣味に合わせたでたらめな対応なんか覚えたくない。
311308:04/07/02 20:40
というよりReadOnlyにする必要がないといいたいんだけど。
そりゃobject.freeze()一発で自動的にしてくれるんならいいけど
C++の仕様はあまりにも変質的だよ。コストに見合ってない。
constタソ…(;´Д`)ハァハァ
const汚染とthrows汚染とGPL汚染はソフトウェア界に蔓延る三大汚染です。
>>311
ぜんぜんそのようにおもったことがない
>>304
constな変数、オブジェクト等を色付きや波線が付いた文字で表示するようにして、"const"という文字を書かないようにする。
ただし、ヴィジュアル環境だけに限定
>>306
>オブジェクトに対するconstは撤廃だろ。
>そんなもんのメリットもない。

あると思うけどなあ…。
finalize()があるなら我慢してもいいけど、ランタイムでの状態の控えが
インスタンスに乗っかる様では、C++の旨味の一つが減る事になるし。

>ついでにオブジェクトの値渡しも撤廃。

まあ、これはそれなりに同意。コンパイラの頑張りで最適化かかることもあるとはいえ、
そもそもその頑張り方でコンストラクタの呼び出し回数が変わる可能性があるのは
恐ろしすぎる。
とはいえ、関数からの返り値オブジェクトのためだけにガベコレ搭載とヒープメモリの使用が義務づけられる様では、これも堪らない。
スタック上に返りオブジェクトを積む事を明示的に指定できるよう言語仕様を拡張してもらえばいいのだろうか。
…余計な文法増えるくらいなら、コンパイラの最適化能力を義務づけてもらう方がマシといえばマシかもしらん。
考えたらリンク時最適化まで必要だな、これ。関数の呼び出しプロトコルに関わる話だ…。

>ついでにコピーコンストラクタも撤廃。

これは善し悪し。でも、宣言したときしか使えないくらいにして欲しいのは確かかな。

>ついでに参照にNULL突っ込めるように変更。

えー…。

まあそのなんだ。Javaの文法にテンプレートが乗るなら、確かにconst無くてもいいわ。
とはいえ、単にポインタからアロー演算子取っ払っただけの実装で
ポインタと(スタックとかに積まれてるかもしれない)オブジェクトの
インスタンスとの区別が言語の上でつけられなくなるのは、漏れ的には困る。
その辺の泥臭いところを使用者が好きに使う事で、性能とのトレードを計れるのが
C++最大にして唯一の強みなんだし、それが無くなるならそんなんいらんわ。
317304:04/07/03 06:47
>>306
> オブジェクトに対するconstは撤廃だろ。
> そんなもんのメリットもない。

ROM環境を考慮すれば、メリットの有無とかそんな問題じゃなくて、単純に「必要」です。
撤廃はありえないと思います。

それぞれの変更案について、それによって現状のどんな問題が解決できるのか、教えてもらえますか?
318304:04/07/03 06:48
>>308
ファイルに読取専用設定ができることと同じくらい自然だと思ってます。
ところで、 object.freeze() って何してくれるんですか?
319304:04/07/03 06:49
>>315
言語仕様の話でお願いします。
Javaマンセー!!!
const逝ってよし!
オブジェクトのconstは確かに微妙。
ビット的constと概念的constの二つの意味を持ち得るのが、最大の問題点。

個人的には、
オブジェクトのconstは、ポインタを保持している場合、
コンストオブジェクトへのポインタに変換できるようにして、
ビット的tかつ概念的constにできれば。

内部状態が変更され得る概念的constは、面倒でもReadOnlyインターフェイスを作る方向で。
グローバル変数はいつ何処で変更されるか分からないから
constだのReadOnlyにしようというのはおかしな話だ。
その変数のスコープを限定するのが筋。
オブジェクトも同様。
>>321
>内部状態が変更され得る概念的constは、面倒でもReadOnlyインターフェイスを作る方向で。
そのためのmutableだろ?
324321:04/07/03 17:11
>323
いや>304のC++の仕様を改良〜に対しての俺案として、

constを完全なビット不変の記号として使えるようにして、mutableも廃止。
今現在の概念的constとしてはconstを使えないようにする。
と、いくらか解りやすくないだろうか?

ということを言いたかったんです。
このスレ終わったな
それはそうと
定数展開が約束される、定数でしか初期化されない修飾子constと、
単に変更不可の修飾子readonlyに分けて欲しくありませんか?
トリックめいた事をする時に、静的に割り当てられたメモリしか指せないポインタはほしいなあ
グローバル変数、関数内static、文字列リテラルのみを指せる修飾子
328323:04/07/03 18:53
>>324
俺が言いたかったのは、mutableの存在からしても、現状のconstは概念的な不変性を表す物であって、
「二つの意味を持ち得る」などと言う事は無いのではないか、と言うこと。
俺の考えでは、組み込み型ではたまたまこの二つの不変性が一致しているだけで、
ユーザー定義型でビット単位の不変性を保証する仕組みは現在のC++には無く、
今後も必要無いように思う。
>>328同意。
このことはほとんど議論挟む余地が無いと思う。
良くも悪くも、C++はそういう言語だ。
c o n s t は ネ 申
C++がエラーを防ぐ為ならいかなるコーディング上のコストを払うのも厭わないというなら
throwsを骨抜きにしているのがどうにも解せないな。
それは確かに解せないなあ。
どうも歴史的な事情らしいんだけど、詳しくないのでよくわからん。
やっぱmainはこうだよな
#pragma warning(disable:4114)
int main(
const const const const const const const const const const const const const const const const const const const const const
const const const const const const const const const const const const const const const const const const const const const
const const const const const const const const const const const const const const const const const const const const const
const const const const const const const const const const const const const const const const const const const const const
const const const const const const const const const const const const const const const const const const const const const
const const const const const const const const const const const const const const const const const const const const const int argc,
const char* const* const argv)
そろそろ誰かconstの使い方のカンペキなルールをまとめてちょんまげ。
付けて困らないところにはすべて付けろ。
そんだけ。
>>333
戻り値にconstが付いていない。-10
>>336
そんな!殺生な!

#pragma warning(disable:4114)

  const const     const const   const const        const const     const
 const    const  const    const const     const const             const const
const              const     const const     const  const const       const
const              const     const const     const             const    const
 const    const  const    const const     const             const     const
  const const      const const  const     const const const        const          int main(const int argc, const char* const* const argv)
>>337
プログラミング言語C++の !でNULLって書いてるの思い出した。
あとからメンバ関数にバンバンconstをつけて、
「なんかこう、引き締まっていくカンジ〜♪」を楽しむのが趣味なのですが、
僕はフェチ板に書き込むべきでしょうか?
>>339
フェチは産まれた時から引き締めてないと。
むしろダイエット板に書き込め。
つい癖で片端からconstつけてしまう。
お蔭で、ただの雪駄にまでconstをつけてしまい、溜息を吐きながら外す日々。
classのメンバはconstは付くか付かないか明確だろ
>>342
「メンバ」ってメンバ変数とメンバ関数の両方のこと?
何と比べて、なぜ明確なの?
あるメンバにconstがつくかつかないか迷うことなんてないだろ。
>>344
だから、何を根拠にいってんの?
メンバにconstってのがわからんが、constつけるかつけないかで
迷う事は確かにないな。

あるのはごくたまにパフォーマンス上の理由かなんかで
外さなきゃならんかと苦悩したり
mutable使っちまえば楽になるかと苦悩したり
なんで藻前その宣言constじゃないんだよ漏れ様にconst_castさせようってかぬっころすと
殺意抱いたり、そんなレベルの悩みだよな。
明確じゃないという主張があるなら聞きたい
おっちゃん、それは卑怯だ。
言い出しっぺがいきなり背理法もないだろう。
349344:04/07/09 02:04
>>348
経験的に迷ったことがないし迷うようなケースが思いつかないんだからしょうがない。
で、自分の経験として明確でなく迷ったケースはあるのか?
>>349
論理的constと物理的constの狭間で迷うことが幾度かあったな。
遅延初期化、copy on write、proxyっぽいものを作れば現れる問題だと思う。
constは関数のインターフェースを決めるものだから実装とは関係なく
その関数が意味するところによって即座に決まるの。
>>348
背理背理法背理法ほっほー♪
>>352
背理っ背理っふれっほっほー♪

「粘着にはなるなよ?」


まーるーだーいー…
>>351
もまえ>>350の言ってる事わかってないだろ。

それはさておき、>>351の言うレベルで迷う事なんかないのは自明だとは思う。
頭悪い発言スレに乗せたいくらいだが、「ビルドエラーでない限り全部const」でFA。
const_cast最強ってことで
>354
このスレをmutableで検索してみると
わかってる奴と、わかったようなつもりになってる奴が
再三同じ議論を繰り返してる。
わかったつもりになってる奴の方が偉そうなのも、まったく同様。
>>356
えーと、>>351が「わかってる奴」で、それと違う意見を述べた>>350は「わかったつもりになってる奴」
ってことかい?
351が原則で
350が実践上ぶちあたるところだな
>>357
逆だろ、どう見ても。
俺はmutableが必要になったのはclass内にキャッシュを持たせようとした時くらいかな。
361s:04/07/12 19:51
>>354の言うように, 全てにconstを付けたいのだけど… むしろそうする位なら,

・デフォルトが従来のconst
・変化する変数にのみmutableを付ける

世の中にそんな言語は無いものかな?,などと愚考する.
関数型言語だと行き過ぎなんだよなあ.

スレ違いスマソ.
むしろすべてにconst付けない。のほうがよっぽど現実的だな。
人の設計したクラスのconst引数を
「コンパイルが通らないので」という理由で
すべてキャストしてる新人を説教するのに疲れました
>>331
遅レス。
例外中立なテンプレートを作るときに困るからじゃないの?
JavaはC++ほど例外の出番が多くないから、「このコールバックで
例外投げるべからず」とthrows Exceptionで間に合っているけど、
C++だと3歩歩けば例外が飛ぶからねえ。
俺はJavaの方が例外の出番が多かった気がしたんだが、気のせいか
うん、気のせい。
Javaのメモリ不足はErrorだもんね。
367s:04/07/15 21:10
???

>>364
Javaのほうが C++よりも 例外を使うケースが多いに一票.
もし違うというのなら, 例えばどこのベンダのどのC++のライブラリで例外を多用している?
new演算子ですら デフォルトでは例外を投げないような設定を採用している処理系もあるのに.
俺が知らないだけ?


対してJavaでは標準ライブラリにすら例外指定が頻繁に使われている. IOException然り.


#蛇足だけれどメモリ不足はOutOfMemoryErrorといって,
#Errorクラスを継承しているけれど「例外」に分類して構わない..
#(これは逆に,全然使わない印象があるけれど…?)
自分で例外を投げる機会のことを例外の出番って言ってるんじゃないのか。
369367:04/07/15 21:56
>>368
どちらにせよ, C++で例外投げたりはしないというのが 漏れの印象なのだけど.
また処理系の話になって恐縮だけど,例えばVC++の幾つかのバージョンはデフォルトで例外オフだし.
Javaのほうが例外クラスを定義して,よく投げたりするというのは,漏れだけの印象じゃないと思う.
(多分.)

また,C++をやっていたころは,「例外は本当に例外的な場合にのみ使え」と教えられていたので,
Javaの投げまくりスタイルを見て驚いた記憶がある.

#スレ違いスマソ.
その所為で例外使えってうるさい人間が大量生産されてるわけだけどな
>>364
例外中立性についてはJava も Generics 登場してくると似たような状況に
なるような気がする・・・ ←このへん識者が出てきて解説して欲しい
372デフォルトの名無しさん:04/07/21 23:58
const char* func (const char* const) const;
例外がC++で不遇かこってるのは、多分に歴史的事情によるものだと思うんだけど、どうだろ。
オブジェクトの解体周辺の処理が引っ掻き回されるのも大きい。
Javaはその辺考えなくて済むしね。
通信処理なんて、例外投げまくりだ。

返り値だけじゃ情報量少ないし、コードもすっきりするし、
使えるもんなら使いまくりたいけど、如何せんオーバーヘッドでかすぎ、
制御しづらすぎでどうにも。
>>367
> もし違うというのなら, 例えばどこのベンダのどのC++のライブラリで例外を多用している?
すべてのベンダの標準ライブラリ。以上。
>>371
JavaのGenericsはコンテナを型安全にするだけでしょ?
Javaのコンテナはアサーション的な例外しか投げないから、
別に悩むこともない。例外中立が問題になるのは、主に
Template Methodのような場合だと思う。
>>375
>すべてのベンダの標準ライブラリ。以上。

やっぱJavaの方が例外の使用が多いと思えるんだが
377デフォルトの名無しさん:04/07/30 14:29
typedef const char *PCSTR;
typedef char *const PSTRC;
>>377
constはすばらしいが、そのハンガリアンみたいな変な変数名やめろ。
ハンガリアン自体MS流と言われてしまえばそれまでだが、
ポインタ「型」をP憑きで定義するのは、いかにもMS流だな。
>>376
やっぱり実装上の問題だよ。
C++はデストラクションの負荷の問題もあって、例外は基本的に
「使わないほど軽い」処理になってしまってるけど、
Javaではお手軽で安価な通信手段として完成している。

文字通り、フォローしきれないエラーは例外だから、
後よろしくって書けてしまうのはC++には無い魅力。

…別にJavaの例外が特別優秀というわけじゃなく、
単にJava自体が遅い中に処理の負担が埋もれてるだけな
気もしないでもないけど、それはきっと不勉強な漏れの勘違い。

そしてスレ違いsage
typedef enum による型セーフの利用も、コンパイルでのミス発見には
激しく役に立つわけだけど、こういう人間のポカミスに対して
コンパイラのエラーチェック能力を積極的に活用する自衛(?)プログラミングの
スタイルに、何か特別な名前とかあるのかな。

いや、常識の範疇にスタイルも何もないだろ、とか言われちゃえばそれまでなんだけど。
そうか、enumって型だったな
int定数定義以外の目的で使ったことが最近ないや

しかし、typedefせんでも、

 enum Foo { ... };
 Foo f;

とか書けば動くんと違うか?

あと、enumはとてもまともな列挙とはいえんから、
classでまともな列挙を実装したほうがいいような
まあそれでも、PascalやAdaの列挙には絶対勝てないが
>しかし、typedefせんでも、

問題ないですな。C++なら。
Cなら必要。


>classでまともな列挙を実装したほうがいいような

いつも思うんだが、みんなそれ本当にそう思ってるもんなのかな。

enumには、うっかり別の値が紛れ込むのをビルド時にブロックしてくれるって
それ以上の機能は期待しないでもいいんじゃなかろうか。
ちょっとしたクラスの内部状態を外に公開したり、外からの指定を受け取るのにも
enum型は手っ取り早く扱えて便利だと思うんだけど。

ちょっとしたステートマシン書くのにもクラス引っ張りまくりは
あまりに距離が遠すぎ&可読性落ちすぎつーか、
逆に言えばそのレベルで書く必要のあるものには、そもそもenumの
居場所なんかない気がする。
>>382
もしよかったらそのPascalやAdaの列挙にあってC++の列挙にない機能を
解説していただけないでしょうか?
enum ではビットフラグが表現できないことかな?
enum | enum ⇒ int になっちゃう。
>>385
なるほど.
列挙でビットフラグの表現ってどうやるんだ?
>>387
enum Enum0 {E0 = 0x1, E1 = 0x2, E2 = 0x4, E3 = 0x8};
Enum0 enum0;
enum0 = E0|E2;
PascalやAdaは知りませんが,C++だとこういう感じじゃないですか?
で,385の指摘は上記の3行目がエラーになってしまうということだと理解しました.
PascalやAdaだと1行目の割り振りも,自動で書けたりするんでしょうか?
>>387
enum Bit
{
HOGE = 0x01,
FOO = 0x02,
BAR = 0x04,



};
って具合
390Pascalだとこう書ける:04/07/31 11:34
type myenum = (e1, e2, e3);
type myenums = set of myenum;
var n: myenums;
begin
 n := [e1];
 n := n + [e2];
 if e3 in n then ...
>>390
これだと,C++ではクラスで実装ってことになるでしょうね.

>>383
> 可読性落ちすぎつーか、
可読性はマクロ使えばそんなに悪くはならないですよ.
参考として、C#の場合:
[Flags] public enum MyFlag { H0 = 0, H1 = 1, H2 = 2, H3 = 4, H4 = 8 }
Console.WriteLine(MyFlag.H1 | MyFlag.H4); ⇒ H1, H4

enum は自動連番+α だと割り切れば便利。
>>385,390
今,試してたらこんなのできたんですけど,ダメですか?
#include <iostream>
using namespace std;
enum Enum0 {E0 = 0x1, E1 = 0x2, E2 = 0x4, E3 = 0x8};
int main () {
Enum0 enum0 (static_cast <Enum0> (E0|E2));
cout << (enum0 & E0 ? true : false) << endl;
cout << (enum0 & E1 ? true : false) << endl;
cout << (enum0 & E2 ? true : false) << endl;
return 0;
}
それならunsigned intでいいじゃん。と思ったり。
>>390
C++に単純に置き換えると、こうかな。重いな。
enum myenum {e1, e2, e3};
typedef std::set<myenum> myenums;
myenums n;
{
 n.insert(e1);
 n.insert(e2);
 if (n.find(e3) != n.end()) { ...
>>394
それは問わないことにしてたんですが(笑).

「ビットフラグの表現」以外にはPascalやAdaの列挙にあってC++の列挙にない機能ってあるんですかね?
ないよ。
>>395
393風にやると
enum myenum {e1 = 0x1, e2 = 0x2, e3 = 0x4};
myenum n (static_cast <myenum> (0));
{
n = static_cast <myenum> (n | e1);
n = static_cast <myenum> (n | e2);
if (n & e3) {...
return 0;
>>398
そういう使い方をするときは、 n の型を myenum にしちゃダメだと思う。
キャストしてまで myenum 型にしても、結局保持している値が
列挙された値になるわけでもないのだから、 myenum 型は不適。
400398:04/07/31 12:34
もう少し改良してみました.
#include <sl/debug_tool.h>
enum myenum {e1 = 0x1, e2 = 0x2, e3 = 0x4};
myenum &operator |= (myenum &p0, const myenum &p1) {
return p0 = static_cast <myenum> (p0 | p1);
}
myenum n (static_cast <myenum> (0));
{
n |= e1;
n |= e2;
if (n & e3) {...
>>399
あぁそっか.失礼しました.
>>395
こうすると軽くなるのでは?
enum myenum {e1, e2, e3};
typedef std::bitset <e3 + 1> myenums;
myenums n;
{
n.set (e1);
n.set (e2);
if (n.test (e3)) {...
ビット表現に使い出した時点で、列挙型じゃなくてただの定数だしね。
値の受け取りも結局ただのintでしかなくなっちゃうので、
コンパイル時のエラー検出云々は一切できないし。

話がズレるけど、enumがその辺の責任まで負わされちゃってるのは

static const int CONSTANT = 0xdead;

みたいな定数式を、クラスメンバの定義に書いとくことができない
比較的古めのコンパイラのせいもあって、慣習的にそうなっちゃてるだけで、
enumをビット操作用(に限らず、任意の値の定数の定義)に使うのは、
列挙という意味では確かに正しくは無いという認識でOK?
>>402
その場合、bitsetのテンプレート引数の保守が問題になる。
そのソースで列挙値にe4を追加したらマズイし、
列挙の最後に個数を取るための値を置くと、
列挙型として中途半端な型になってしまう。

「enum だけで〜」スレが要るかな?
もし次スレが立つことになったら、それで逝こう
適当な使い方だとは思わないが、正しくないわけではないと思う。
>404
boolやenumをintで代用する奴は氏んだ方がよい
http://pc5.2ch.net/test/read.cgi/tech/1060556404/
>>407
よく510も続いてるな...
409402:04/07/31 14:58
>>403
enumをビット表現に使う正当性はともかく(そんなの分かりません.),
「Pascalごときに負けられん.」ということで(笑),402を型の恩恵を受けれるようにしてみました.
using namespace std;
enum myenum {e1, e2, e3, myenum_size};
template <typename E, size_t SIZE>
class Bitset: private bitset <SIZE> {
typedef bitset <SIZE> Base_;
public:
Bitset &set (E p) {return static_cast <Bitset &> (Base_::set (p));}
bool test (E p) const {return Base_::test (p);}
};
typedef Bitset <myenum, myenum_size> myenums;
myenums n;
{
n.set (e1);
n.set (e2);
if (n.test (e3)) {...
std::bitsetでコンパイル時にサイズ取れたら,テンプレート引数を1つにできるんですけどね.
410402:04/07/31 16:03
>>409
最後の一行は撤回します.やっぱ無理でした.
替わりと言っちゃなんですが,
- typedef Bitset <myenum, myenum_size> myenums;
+ #define BITSET(arg) Bitset <arg, arg##_size>
+ typedef BITSET (myenum) myenums;
とすれば引数は一応減らせました.あんまり美しくないですけど.
>std::bitsetでコンパイル時にサイズ取れたら
template<typename StdBitSet> struct size;
template<int Size> struct size<std::bitset<Size> >{enum{value=Size};}; // static const intを使うべきか?
こういう事?何の役に立つか分からんが。
412411:04/07/31 16:16
失礼 リロードしてなかった。
列挙で負けてるのは設計思想の違いが原因なのに
「Pascalごときに負けられん.」とは厨房丸出しだな

その調子で部分範囲型も実装してみてくれよ
ちゃんと、部分範囲型は親の型と一方通行の互換性があって、
列挙以外に、整数や文字型にも使えるやつでよろしく頼む

あと、Adaじゃ文字型は当然列挙型なんで
enumで文字型も実装よろ
>>413
なんでそんなに偉そうなの???
別にえらそうじゃなくて
負けられないなら
これぐらいは最低限要るという項目を挙げただけ
>>402
なんでわざわざ std::bitset つかうんだ?
operator | をサポートし、四則演算をサポートしないような
整数ラッパーを作ればいいだけだと思うが。

まぁ、ビットフラグは、
(幾つかのうちからひとつ)|(他の幾つかのうちから一つ)
みたない要求をされる場合もあるので、
あんまりがんばっても報われない(要求を満足できない)かもしれん。
417402:04/07/31 22:52
>>413
まぁできることならリア厨に戻りたい今日この頃.orz
その「部分範囲型」ってのはPascalかい?
サンプルコードでも交えてもう少し詳しく解説よろしく.
それと最後のパラグラフの内容もC++しか知らん私には意味不明.

>>416
私自身はenumにこのスレで要求されてる機能を求めてはいないんですが,(383氏の考え方に近いです.)
まぁ頭の体操に.(笑)
bitset使ったのはビット長に制限ないのがいいかなと思いまして.

ってかそろそろスレ違いですかね?
同じPascal好きの人間として>>413のような喧嘩腰はいただけないが、
横から解説させてもらうと、

部分範囲型は type From100To200 = 100..200; とか書けば100から200までしか代入できない型を作れる機能。
このときメモリサイズは最小のものを自動選択。この場合unsigned charかな。
(Pascalでは逆にCのintやlongに相当する予約語が無くて、整数は全部こうして使う。既定義のは当然あるけど)

で、整数以外にも既にあるenum T {A,B,C,D}にもtype T2 = B..C; とかできて、動作は上記同様。
これも大きい方から小さい方への代入はチェックが入る。
整数、enumの他、bool, 文字型も同様。type UpperAlphabet = 'A'..'Z'; とかできる。

そして上記の型すべて、setに使える。(setの下限は0に限らない)

templateでできそうなのを言語仕様に抱え込んで…とか思われるかもしれないが、
こういうのはリテラル定数の扱いにまで影響するので、内心templateでカバーできる範疇外と考えるけど
頭の体操は俺も好きなのでどんどんやってください。
419デフォルトの名無しさん:04/07/31 23:35
>>415
要するに「厨房丸出し」の理屈に乗っかって
乞食やってるんですね ;-)
420デフォルトの名無しさん:04/08/01 00:06
>部分範囲型は type From100To200 = 100..200; とか書けば100から200までしか代入できない型を作れる機能。
assert使えばいいのに・・・
>>420
NDEBUG定義したら消えてしまうassertをどう使ったら実装できる?
範囲型なんてあっても、どうせユーザ定義型で破綻するからイラネ。
多次元型になった時点で、すでに意味を成せない。
>>420 静的なチェックの他、サイズの自動選択という側面もある
>>422 Adaにはgenericがあるから複素数とかそれで実装されてる
誰かboostあたりをあさってきてくれ。
既にあるか、無いなら価値なしと判断されたかのどっちかだ、きっと。
そらまー、今の話はあくまで頭の体操であって、どっちみち完璧な再現は無理だし
それにC系の言語にはこんなもん無くても現に用は足りてるし
>>424 smart_enum でググれ。
>>426
クスコ。
>>418
別に俺はPascal好きではないぞ、「設計思想の違い」と思ってる

charだろうが全部整数型で済ませるCの基本理念は
コンピュータの動作に忠実だし、便利といえば便利
数字でない文字型とか、部分範囲とか、別になくても困らないものを
わざわざ実装しないのも、利口ともいえる

そういう単純なモデルの中に、後付で列挙を入れたものだから
列挙がいまいちなのもあたりまえ


逆に、離散型という概念があり、その中にさらに整数と列挙を導入して、
という感じに哲学的概念から設計されてるのが、Pascalやその発展のAda
列挙でCに勝手あたりまえ

>>420
type num_letter = '0' .. '9' ;
var count_num_lentter : array [ num_letter ] of integer;

とか、範囲チェック以外にも使うのよ
Adaだと

for i in num_letter'range loop
 ...
end loop

とかループの範囲指定も出来るし


可読性・保守性をあげるのが主な目的と思う
>>420
なんで人間 (=プログラマー) が苦労せんといかんの ?
コンパイラーにやらせられることはコンパイラーにやらせようよ。

と言う発想なわけ。
反面、かったるいところも多いから、一長一短。
部分範囲型簡単に作ってみたけどこんな感じ?

template<int N>struct NI;
template<>struct NI<1>{ typedef unsigned char type; };
template<>struct NI<2>{ typedef unsigned short type; };
template<>struct NI<4>{ typedef unsigned int type; };

template<int MIN,int MAX>
class RangeInt{
typename NI<((MAX-MIN)>255) ? ((MAX-MIN)>65535) ? 4 : 2 : 1>::type value;
public:
RangeInt(int val=MIN){
if(val<MIN || val>MAX)
throw;
value=val-MIN;
}
operator int() const{ return value+MIN; }
};

RangeInt<5,10> ri=7; //5〜7までの整数型
ミス

>//5〜7までの整数型

5〜10までの整数型を7で初期化
>>430
それ環境依存じゃん
>>432
boost入ってない奴用に簡単に試せるのを出しただけ
CHAR_MAXとかは面倒だからはしょった

入ってる奴用

template<int MIN,int MAX>
class RangeInt{
typename boost::int_max_value_t<MAX-MIN>::least value;
public:
RangeInt(int val=MIN){
if(val<MIN || val>MAX)
throw;
value=val-MIN;
}
operator int() const{ return value+MIN; }
};
足したり引いたりせんでもいいんじゃね?
435402:04/08/01 19:40
>>418
解説サンクス.413で厨房言われる理由が分かった.(冷汗)
これはもうちょい煽るか煽てるかしないと出ないよ.>>413
(「あおる」と「おだてる」は同じ字なんだね.)
436402:04/08/01 19:51
433は範囲超えると例外送出する見たいですが,Pascalの場合って範囲超えるとどうなるんでしょね?
418には「大きい方から小さい方への代入はチェックが入る。」とありますけど,
1. 「型」らしくコンパイル段階ではじく.
2. 例外.(ってあるの?)
3. 自動拡張.
3の場合は「型」っぽくないですが.
コンパイル段階で確実にはじけるものはコンパイルエラー、
実行時で無いとわからないものは、実行時チェック。(勿論コンパイルオプションによりリリース時はチェックを省ける)
チェックに引っかかった場合、古典PascalならCのシグナルハンドラみたいな、Delphi,FreePascal等は例外

…なんですけども、Pascalの動作を真似る必要は無いと思います
範囲制限型をテンプレートで実装するのは悪くないんだけどね。
ただ、連想コンテナや標準のvectorあたりで十分フォローできる範囲な気がする。

constで飯が3杯食えるこのスレ的には、見て即エラーと分かり、
コンパイラがエラーですよと即警告してくれる、そのまんまのenumの使い道について
検証した方がいい気もする。

検証もへったくれも、答えは出きってるんじゃないかって感じだけどね。
要は外部からの入力の範囲を規定するのに、最小限の労力で「シンボル」を設定できて、
シンボルの範囲外を簡単に突っぱねられるtypedef enumマンセーだと言いたかったんだけど
それがこういう方向に膨らむとは考えてもみなかった。
面白いからもっとやろう。
集合型はは複数の範囲を持てたりする

alpha = ['A'..'Z', 'a'..'z'];
'A'..'z'でいいじゃん
ASCIIコード表見たことないのか?
000 0000 ^@ 032 0x20 064 0x40 @ 096 0x60 `
001 0x01 ^A 033 0x21 ! 065 0x41 A 097 0x61 a
002 0x02 ^B 034 0x22 " 066 0x42 B 098 0x62 b
003 0x03 ^C 035 0x23 # 067 0x43 C 099 0x63 c
004 0x04 ^D 036 0x24 $ 068 0x44 D 100 0x64 d
005 0x05 ^E 037 0x25 % 069 0x45 E 101 0x65 e
006 0x06 ^F 038 0x26 & 070 0x46 F 102 0x66 f
007 0x07 ^G 039 0x27 ' 071 0x47 G 103 0x67 g
008 0x08 ^H 040 0x28 ( 072 0x48 H 104 0x68 h
009 0x09 ^I 041 0x29 ) 073 0x49 I 105 0x69 i
010 0x0a ^J 042 0x2a * 074 0x4a J 106 0x6a j
011 0x0b ^K 043 0x2b + 075 0x4b K 107 0x6b k
012 0x0c ^L 044 0x2c , 076 0x4c L 108 0x6c l
013 0x0d ^M 045 0x2d - 077 0x4d M 109 0x6d m
014 0x0e ^N 046 0x2e . 078 0x4e N 110 0x6e n
015 0x0f ^O 047 0x2f / 079 0x4f O 111 0x6f o
016 0x10 ^P 048 0x30 0 080 0x50 P 112 0x70 p
017 0x11 ^Q 049 0x31 1 081 0x51 Q 113 0x71 q
018 0x12 ^R 050 0x32 2 082 0x52 R 114 0x72 r
019 0x13 ^S 051 0x33 3 083 0x53 S 115 0x73 s
020 0x14 ^T 052 0x34 4 084 0x54 T 116 0x74 t
021 0x15 ^U 053 0x35 5 085 0x55 U 117 0x75 u
022 0x16 ^V 054 0x36 6 086 0x56 V 118 0x76 v
023 0x17 ^W 055 0x37 7 087 0x57 W 119 0x77 w
024 0x18 ^X 056 0x38 8 088 0x58 X 120 0x78 x
025 0x19 ^Y 057 0x39 9 089 0x59 Y 121 0x79 y
026 0x1a ^Z 058 0x3a : 090 0x5a Z 122 0x7a z
027 0x1b ^[ 059 0x3b ; 091 0x5b [ 123 0x7b {
028 0x1c ^\ 060 0x3c < 092 0x5c \ 124 0x7c |
029 0x1d ^] 061 0x3d = 093 0x5d ] 125 0x7d }
030 0x1e ^^ 062 0x3e > 094 0x5e ^ 126 0x7e ~
031 0x1f ^_ 063 0x3f ? 095 0x5f _ 127 0x7f 
[\]^_`よ、さようなら
`\[^_^]
部分範囲は、単にレンジチェックの機能だけでなくて
範囲そのものを、配列の範囲につかって

var count_teenager : array [ 13 .. 19 ] of integer;

とやる代わりに、

type teen = 13 .. 19;
var count_teenager : array teen of integer;

とかやったり、
Adaなら

for i in teen'range loop
 ...
end loop;

とかやって、可読性をあげるのも大きな目的であってだな
単なるレンジチェック付きの型じゃねえし
単なるレンジチェック付きの型なら、それこそassertの類で十分
だぁら、Pascal自慢をするのが目的じゃねーw
あくまでC++で、静的にあれこれどこまで迫れるかであって、文法上そもそも無理があるのはわかり切った事だっての
始点と終点を隠蔽して即値のインデクスから開放されたいなら、お好みの標準コンテナ使おう!
インデクスの値そのものが大事なら連想コンテナ使おう!
enum State { ... };
inline State operator |(State a, int b) { return (State)((int)a|b); }
みたいのは良く書くが
switch 〜 case の case に書くとコンパイルエラーになるのが鬱。
449デフォルトの名無しさん:04/08/13 01:10
そりゃなるだろうなあ。
Javaにはなんかそんなのあったな。
451デフォルトの名無しさん:04/08/18 13:46
                      ''';;';';;'';;;,.,                  ザッ
                       ''';;';'';';''';;'';;;,.,   ザッ
          ザッ            ;;''';;';'';';';;;'';;'';;;
                        ;;'';';';;'';;';'';';';;;'';;'';;;
                        vymyvwymyvymyvy     ザッ
               ザッ     MVvvMvyvMVvvMvyvMVvv、
                   Λ_ヘ^−^Λ_ヘ^−^Λ_ヘ^Λ_ヘ
     ザッ            ヘ__Λ ヘ__Λ ヘ__Λ ヘ__Λ
                __,/ヽ_ /ヽ__,.ヘ /ヽ__,.ヘ _,.ヘ ,.ヘ    ザッ
    /\___/ヽ   /\___ /\___/ヽ _/ヽ /\___/ヽ
   /''''''   '''''':::::::\/''''''   '''/''''''   '''''':::::::\   /''''''   '''''':::::::\
  . |(●),   、(●)、.:|(●),    |(●),   、(●)、.:|、( |(●),   、(●)、.:|
  |   ,,ノ(、_, )ヽ、,, .::::|   ,,ノ(、_, )|   ,,ノ(、_, )ヽ、,, .::::|_, )|   ,,ノ(、_, )ヽ、,, .::::|  / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
.   |   `-=ニ=- ' .:::::::|   `-=ニ= |   `-=ニ=- ' .:::::::|ニ=|   `-=ニ=- ' .:::::::| < ageますよ
   \  `ニニ´  .:::::/\  `ニニ \  `ニニ´  .:::::/ニ´ \  `ニニ´  .:::::/   \_________
   /`ー‐--‐‐―´\ /`ー‐-  /`ー‐--‐‐―´\-‐‐ /`ー‐--‐‐―´\
                      ''';;';';;'';;;,.,                  ザッ
                       ''';;';'';';''';;'';;;,.,   ザッ
          ザッ            ;;''';;';'';';';;;'';;'';;;
                        ;;'';';';;'';;';'';';';;;'';;'';;;
                        vymyvwymyvymyvy     ザッ
               ザッ     MVvvMvyvMVvvMvyvMVvv、
                   Λ_ヘ^−^Λ_ヘ^−^Λ_ヘ^Λ_ヘ
     ザッ            ヘ__Λ ヘ__Λ ヘ__Λ ヘ__Λ
                __,/ヽ_ /ヽ__,.ヘ /ヽ__,.ヘ _,.ヘ ,.ヘ    ザッ
    /\___/ヽ   /\___ /\___/ヽ _/ヽ /\___/ヽ
   /''''''   '''''':::::::\/''''''   '''/''''''   '''''':::::::\   /''''''   '''''':::::::\
  . |(●),   、(●)、.:|(●),    |(●),   、(●)、.:|、( |(●),   、(●)、.:|
  |   ,,ノ(、_, )ヽ、,, .::::|   ,,ノ(、_, )|   ,,ノ(、_, )ヽ、,, .::::|_, )|   ,,ノ(、_, )ヽ、,, .::::|  / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
.   |   `-=ニ=- ' .:::::::|   `-=ニ= |   `-=ニ=- ' .:::::::|ニ=|   `-=ニ=- ' .:::::::| < s ageますよ
   \  `ニニ´  .:::::/\  `ニニ \  `ニニ´  .:::::/ニ´ \  `ニニ´  .:::::/   \_________
   /`ー‐--‐‐―´\ /`ー‐-  /`ー‐--‐‐―´\-‐‐ /`ー‐--‐‐―´\
453マイク ◆yrBrqfF1Ew :04/08/18 15:20
>【C++】 const だけでメシが3杯食えちゃうスレ

食えるわけねえだろが。
メシの種やおかずにはなるだろ
業務中にconstにハマって(2重の意味でw)時間潰してる奴は多そうだけどな
ハマッタ時はconst_cast
constが ついてる/いない おかげで、
全く予想もしないようなパラメータ結合してて
理解不能なバグになることがある

constでハマったらconst_castなんて言ってるうちは素人
foo(int &v);
foo(const int &v);
でオーバーロードして挙動を変えて
生意気な後輩(先輩でも可)をびびらせるというのはどうだろう。
459名無しさん@Vim%Chalice:04/08/19 01:37
>>458
そのオーバーロード出来るって知らなかった。びびった。スマン。
これやられたら const 付けるようになりそうだな…
どうやったらconstでハマるんだよ。わけわからんよ
まったくだ。


>>459
チョメ。
こっちは問題ないだろうと思うけど、fooへの参照を返す関数に

const foo& bar() const
foo& bar()

の2パターン用意する意義はわかってるよね?
>>461
参照の戻り値が変更される場合ってどんなの?
>>462
わかりやすい例だと、
foo & operator[](int)
とか。
464462:04/08/19 11:42
>>463
結果に代入するアフォを阻止するためのやつですね
?
>>464
そうじゃなくてさ、
class hoge
{
public:
 hoge&     operator[](size_t n);
 const hoge& operator[](size_t n) const;
};
非constオブジェクトでは好きに書き換えられるようにするけど、constオブジェクトでも読取限定でoperator[]を使わせたいとか、
あるいはconst版をpublic、非const版をprivateにするとかそういう用途に。
>>466
確かにこれ両方ないと、const な map は [] で中身見ることすらできなくなるね。
>>467
見れないのが普通では?
469デフォルトの名無しさん:04/08/20 18:26
>>468
???
>>469
#include <map>
using namespace std;
typedef map <int, float> Map;
int main () {
const Map m0;
m0 [3]; // <- エラー
const_cast <Map &> (m0) [3]; // <- OK
return 0;
}
vector は const な operator [] があるのに、
map にはないのはどういう理由なんだろう・・・
例によって例外関連?
map<Key, Value>[] で存在しないキーを指定した場合、
そのキーに対して Value() が勝手に挿入されてしまうから。
map.find() を使え。
>>472
超納得。
ある意味とても教科書的な「悪い」constオーバーロード実装例でつね。
>>473
相変わらずお前は意味不明なレスをするんだな
そして、存在しないキーを指定したとき例外を投げる仕様だと
それはそれでまた当然文句をいうのも473。
>>473
悪いというよりは、C++の文法的な問題が絡んでいるのでは。
つまり、map[] = a という代入は operator [] ⇒ operator = という2ステップで処理されるので、
最初の operator [] は Value& を返さざるを得ない。
よって、operator [] で存在しないキーが指定された場合も、
参照だけでなく代入される恐れがあるので、どこかに実体を保持しておく必要がある。
だから、勝手に新しいValueが挿入される。

C# インデクサや、VC++ の __declspec(property) 方言のような、
map[key] = value ⇒ map.insert(key, value) 的な書き換えをしてくれたら、
参照と代入が明確に分離するので、const [] も可能だっただろう。

実は、C++だけでも、プロキシオブジェクトを返すようにすれば
const [] に対応することもできたはずなんだが……なぜそうならなかったのかは知らない。
>>476
> const []
対応する要素が無かったらどうするの?例外?
>>477
代入のときは挿入して、参照のときは挿入せずに Value() を返す。
constなのに挿入するのか?
>>478
const [] の戻り値に代入は無いよな?
それに、 Value() を返すってことは、参照したときの戻り値は参照型じゃないってことになるのか?
>>479
ああ、言い方が悪かった。
non-const [] は、参照と代入の機能を持つプロキシオブジェクトを返し、
const [] は、参照機能だけを持つプロキシオブジェクトを返せばいい。
>>480
> Value() を返すってことは、参照したときの戻り値は参照型じゃないってことになるのか?
YES。
例外を投げない const [] を実現するためには、
存在しないキーが指定された場合に挿入することなく Value() を返すため、
値戻しになることは避けられない。
戻り値に参照型を使う場合は、どこかに実体を保持しなければならないから。

んで、値戻しだと代入(map[] = k)ができなくなってしまうので、
プロキシを介して、参照か代入かが判明するまで評価を遅らせる必要がある。
これが、プロキシを使えば〜の意味。
>>481
const YourMap<const char *, int> m; /* empty map */
int x = m[3];
これはどうなると意図している?
484483:04/08/21 16:17
分かった。ごめん。
>>482
ってことは、
 map<int,value_type> const m;
 value_type const& v1 = m[0];
 value_type const& v2 = m[0];
としたとき、 &v1 != &v2 なわけだな。ちょっと気になるな。

operator [] でプロキシを返すと、
 map<int,map<int,int> > const m;
 int n = m[0].size();
こんなんできなくなりそう。

> const [] に対応することもできたはずなんだが……なぜそうならなかったのかは知らない。
要素が無かった場合への対応がいろいろ考えられるし、
std::map自身の立場ではどれが一般的とも言えないからでしょ。
たとえば>>482のような対応が常に正解とは言えないし、
そういう対応が適している場合には、std::mapを拡張して実装すればいい。

こんなこというと、 operator [] 自体がダメだったとも言えるけど、
実際のところダメだったんじゃないかと思う。
C++では . をオーバーロードできないから、参照を完全に真似ることが出来ない
よってプロキシクラスに参照機能なんて持たせられない。
>>485
それらは実現できないな。
ポインタ格納専用でよいなら、
見つからない場合はNULLが変えるのは妥当だし、
プロキシの operator -> () をオーバーロードできるから、
それなりに使いやすいかも。
>>487
> 見つからない場合はNULLが変えるのは妥当だし、
> プロキシの operator -> () をオーバーロードできるから、

それ、std::mapにイテレータでアクセスすれば同じことじゃない?
結局のところ、俺は現状のmapで満足してます。
                      ''';;';';;'';;;,.,                  ザッ
                       ''';;';'';';''';;'';;;,.,   ザッ
          ザッ            ;;''';;';'';';';;;'';;'';;;
                        ;;'';';';;'';;';'';';';;;'';;'';;;
                        vymyvwymyvymyvy     ザッ
               ザッ     MVvvMvyvMVvvMvyvMVvv、
                   Λ_ヘ^−^Λ_ヘ^−^Λ_ヘ^Λ_ヘ
     ザッ            ヘ__Λ ヘ__Λ ヘ__Λ ヘ__Λ
                __,/ヽ_ /ヽ__,.ヘ /ヽ__,.ヘ _,.ヘ ,.ヘ    ザッ
    /\___/ヽ   /\___ /\___/ヽ _/ヽ /\___/ヽ
   /''''''   '''''':::::::\/''''''   '''/''''''   '''''':::::::\   /''''''   '''''':::::::\
  . |(●),   、(●)、.:|(●),    |(●),   、(●)、.:|、( |(●),   、(●)、.:|
  |   ,,ノ(、_, )ヽ、,, .::::|   ,,ノ(、_, )|   ,,ノ(、_, )ヽ、,, .::::|_, )|   ,,ノ(、_, )ヽ、,, .::::|  / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
.   |   `-=ニ=- ' .:::::::|   `-=ニ= |   `-=ニ=- ' .:::::::|ニ=|   `-=ニ=- ' .:::::::| < ageますよ
   \  `ニニ´  .:::::/\  `ニニ \  `ニニ´  .:::::/ニ´ \  `ニニ´  .:::::/   \_________
   /`ー‐--‐‐―´\ /`ー‐-  /`ー‐--‐‐―´\-‐‐ /`ー‐--‐‐―´\
                      ''';;';';;'';;;,.,                  ザッ
                       ''';;';'';';''';;'';;;,.,   ザッ
          ザッ            ;;''';;';'';';';;;'';;'';;;
                        ;;'';';';;'';;';'';';';;;'';;'';;;
                        vymyvwymyvymyvy     ザッ
               ザッ     MVvvMvyvMVvvMvyvMVvv、
                   Λ_ヘ^−^Λ_ヘ^−^Λ_ヘ^Λ_ヘ
     ザッ            ヘ__Λ ヘ__Λ ヘ__Λ ヘ__Λ
                __,/ヽ_ /ヽ__,.ヘ /ヽ__,.ヘ _,.ヘ ,.ヘ    ザッ
    /\___/ヽ   /\___ /\___/ヽ _/ヽ /\___/ヽ
   /''''''   '''''':::::::\/''''''   '''/''''''   '''''':::::::\   /''''''   '''''':::::::\
  . |(●),   、(●)、.:|(●),    |(●),   、(●)、.:|、( |(●),   、(●)、.:|
  |   ,,ノ(、_, )ヽ、,, .::::|   ,,ノ(、_, )|   ,,ノ(、_, )ヽ、,, .::::|_, )|   ,,ノ(、_, )ヽ、,, .::::|  / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
.   |   `-=ニ=- ' .:::::::|   `-=ニ= |   `-=ニ=- ' .:::::::|ニ=|   `-=ニ=- ' .:::::::| < ageますよ
   \  `ニニ´  .:::::/\  `ニニ \  `ニニ´  .:::::/ニ´ \  `ニニ´  .:::::/   \_________
   /`ー‐--‐‐―´\ /`ー‐-  /`ー‐--‐‐―´\-‐‐ /`ー‐--‐‐―´\
492デフォルトの名無しさん:04/08/24 00:10
                      ''';;';';;'';;;,.,                  ザッ
                       ''';;';'';';''';;'';;;,.,   ザッ
          ザッ            ;;''';;';'';';';;;'';;'';;;
                        ;;'';';';;'';;';'';';';;;'';;'';;;
                        vymyvwymyvymyvy     ザッ
               ザッ     MVvvMvyvMVvvMvyvMVvv、
                   Λ_ヘ^−^Λ_ヘ^−^Λ_ヘ^Λ_ヘ
     ザッ            ヘ__Λ ヘ__Λ ヘ__Λ ヘ__Λ
                __,/ヽ_ /ヽ__,.ヘ /ヽ__,.ヘ _,.ヘ ,.ヘ    ザッ
    /\___/ヽ   /\___ /\___/ヽ _/ヽ /\___/ヽ
   /''''''   '''''':::::::\/''''''   '''/''''''   '''''':::::::\   /''''''   '''''':::::::\
  . |(●),   、(●)、.:|(●),    |(●),   、(●)、.:|、( |(●),   、(●)、.:|
  |   ,,ノ(、_, )ヽ、,, .::::|   ,,ノ(、_, )|   ,,ノ(、_, )ヽ、,, .::::|_, )|   ,,ノ(、_, )ヽ、,, .::::|  / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
.   |   `-=ニ=- ' .:::::::|   `-=ニ= |   `-=ニ=- ' .:::::::|ニ=|   `-=ニ=- ' .:::::::| < ageますよ
   \  `ニニ´  .:::::/\  `ニニ \  `ニニ´  .:::::/ニ´ \  `ニニ´  .:::::/   \_________
   /`ー‐--‐‐―´\ /`ー‐-  /`ー‐--‐‐―´\-‐‐ /`ー‐--‐‐―´\
493デフォルトの名無しさん:04/08/24 12:24
void function( const int a, const float b);

intだろうがfloatだろうが引数には絶対constをつけたくなるんですが、
これはconst病ですか?
/// 文字列をMMXやらSSEやらつかって高速にコピーします。
char* strcpy_special( char* out_str , const char* in_str );





char* strcpy_special( char* out_str , const char* in_str )
{
strcpy( out_str , "in_str" );
strcpy( const_cast<char*>in_str , "世の中そんなに甘くないよ。");
return 0;
}
>>493
そのconstは宣言において意味が無い。それでも付けたくなるようなら病気かも。
gcc,bcc,VC++を調査した結果の結論
「constをたくさん使いたい人は、VC++を使うべし」

void f(const const const char const * const p) { ... }

これがエラーにならずにコンパイルできるのは、上記3つの中ではVC++だけだった。
gccは.cなら警告のみだが、.cppだとエラーになる。
bccは.cでもエラーになる。

もう一度。
「constをたくさん使いたい人は、VC++を使うべし」
>>496
C++ FDIS 7.1.5 - Type specifiers [dcl.type] より、引用。
"redundant cv-qualifiers are prohibited except when introduced through the use of typedefs or template type arguments, in which case the redundant cv-qualifiers are ignored."
「重複するcv指定は、typedefまたはtemplate引数を介した(無視される)場合を除いて禁止されている。」

VC++がユルい。
>>495
>そのconstは宣言において意味が無い。

意味はあるんですけど。
>>498
定義においては確かに意味があるが、宣言においては無い。
>>493
auto変数にも積極的にconstを付けようというのであれば、その一環として、値渡し
の引数にconstを付けるのもアリだと思う。関数の外には何も影響はないけれど。
>>499
これ、揚げ足取りみたいだけど現実なんだよな。
初めてみたときビビったよ。
なんでそんな振る舞いになってるんだろ?
>>501
関数宣言をインターフェースとして使う側から見たとき、
それらの2つに違いがないからだろう。
こういうのはconstに限らず、配列引数→ポインタ引数みたいな同一視は元のC言語にも有った。

また、もしこんなオーバーロードが有効だとすると、
 int f(int);
 int f(int const);
こんなコードを
 int x = 1;
 f(x);
const大好きなプログラマがこう変えたりすると、
 int const x = 1;
 f(x);
呼び出される関数が変わりうることになる。
怖すぎるし、納得いかない。
値渡しを言語からなくせば解決
>>503
むしろ値渡しのみにして
あとはコンパイラでよろしくやってもらう方がいい
引数を値渡しにするか参照渡しにするかはコンパイラに判断させるべきだよな。
その為には引数は常にread-onlyになるけど。
>>502
引数のconstは関数の内側の問題なのに、
それが関数外側のオーバーロードの解決ルールに
適用されちゃうことになっては本末転倒だから、ていうこと?

そうして考えれば、値渡し参照渡しは問題の本質じゃないんだな。
507デフォルトの名無しさん:04/08/27 15:32
そもそも関数の仕様自体が古い
引数が複数とれるなら、戻り値も複数とれるようにするべきだよな。
( s0, s1, s2 ) = f( a0, a1, a2 )
そうすりゃ引数で参照渡しなんてトリッキーは方法は 使う必要がなくなる。
>>507
構造体……。
コピー時のオーバーヘッド・・・
>>507
boost::tuple(std::pair) + boost::tieなんかもどうでしょ?
509の問題が依然として残りますけど.
>>510
boost::tuple だったらコピーが発生しないから良いんじゃない?
512510:04/08/27 16:04
>>511
んー,tupleならコピーが発生しないという理由が良く分からないです.
むしろtieを使うことによってコピーが余分にかかるくらいかと.
参照渡し、値渡しとか無駄だから無くしたい

戻り値複数にすれば解決!!

つー流れだから、boost::tuple云々はちと違うような。
しかし便利そうではあるな。
おれのVC6じゃつかえないからどうでもいい
>>513
どこが違う?

>>512
tieは普通の代入と変わらない。
>>509
Delphiだと戻り値に構造体返すと
代入先に直接書き込まれるから無駄なコピーは発生しないよ。
だから言語仕様とコンパイラの最適化次第だと思うけど。
>>515
例えばファイルか何かを読み込んで英単語の出現頻度を数えて、
既存の std::map< std::string, int > に追加していくような関数:

void update_word_table(std::map< std::string, int >& table);
みたいなものは、参照無くなったらどういう実装がよいと思う?
参照の使いどころは戻り値だけじゃないし・・・

ポインタで十分ですよ、という意見ならある程度同意できるけど。
>>516
C++でも、大抵の処理系でPODの場合はそうなる。
ただ、コピーコンストラクタを実装してたり内部にオブジェクトを保持した
構造体(クラス)を返すと、一時オブジェクトが作られる。
C/C++で、構造体を返す関数
struct hoge f(void) {}
は、実際には、最適化されて
void f(struct hoge *p) {}
と同様の処理になるのが殆ど。
>>517
なるほど。でもそれだと、
>戻り値複数にすれば解決!!
に対する疑問だよな?

>参照無くなったらどういう実装がよいと思う?
void update_word_table(boost::function<void (std::string, int)> inserter);
かな。挿入だけじゃなくて色々やるならmapをじかに扱うんじゃなくてクラスに入れる。
class Base {
public:
virtual int get_prop() const { return 0; }
};

のget_propをオーバーライドしようとして

class Derived : public Base {
public:
virtual int get_prop() { return 100; }
}

とやって半日悩んだ。
仮想関数はconstにしない、というのが俺のスタンダード
>>521
俺もやったわ。
それも今日。
ぬるぽ。


>>522
RTTIチックなことする場合でもconstつけないと、君は!
十分3杯食えてますなぁ。
かれこれ5ヶ月。
>>519
漏れはもうパフォーマンス上の問題は表面化してから考える
プロファイル至上主義に切り替えて、豪快にクラスも構造体も
ガバガバコピーしまくり返り値にしまくりなんだけど、
実際にRVOってどの程度まで効いてるもんなんだろね。

コピーやコンストラクションに変な副作用のない
(staticメンバで生成数をカウントしてるとか)限りは、
確かに大抵のコンパイラで思ってたよりも遥かに気を
まわしてくれてるみたいだけど、盲信するのも微妙な気がするし。

VC7だったかが、中身がfloat3つの簡単なの三次元ベクトルのクラス
(もちろんoperatorで四則演算返り値返しまくり)3つを
足したり引いたり外積かけまくったりして、最終的に3行3列の
マトリクスにしたものを更に値で返す手抜き関数を書いて
逆アセしたら、しれっと返り値の格納先の3行3列の9パラメータを
直接初期化する式に全展開されてて愕然としたことがあるけど、
(それどころか使った三次元ベクトルクラスを定数展開できるとみるや
9個のfloatで直接初期化する芸当までやってのけてた)
これはそれなりに恵まれた例だろうし。

でも、一々細かいこと気にして生産性落とすのも、この時代ナンセンスですかね。
ポインタ引数や参照引数ではなく、値引数にconst付けるのって意味ある?
>>526
宣言にとっては意味無し。
定義にとっては意味がないこともないけど俺は付けない。
>>526
副作用を持つ非 const なメンバを持つクラスなら普通に有意味。
でも普通そんな引数は const 参照にするだろうから、結局無意味か。
529526:04/09/11 01:55:05
>>527
> 定義にとっては意味がないこともない
詳細キボンです

>>528
あー、確かに… 仮引数をクラスへのconst参照にしたら
その関数内部からはconstメンバ関数しか呼べないですし、
(publicな)メンバ変数ならreadしかできませんね…


そもそも仮引数にconstを付けるのって、呼び出し側に
「中身を書き換えませんよ〜」って知らせてあげる効果がありますよね

基本型(int/char等)でも集合型(struct/class)でも値引数ならコピーされるから
呼び出し側は渡した実引数を変更される心配をしないですよね?
なので、中身を書き換えられる心配は無いのだから
わざわざconstつけなくても良いのでは… ということです

現実的には、コピーするとコストかかっちゃうから、
基本型じゃなければ、おっしゃる通りに参照(とかポインタ)にするでしょうし、
更に関数内で書き換えない場合はそれを呼び出し側に知らせるためにもconstにすると思います
# 実際に関数内でconst引数の中身を書き換える操作をしようとすれば
# コンパイルエラーになりますし

長文スマソ
530デフォルトの名無しさん:04/09/11 02:42:28
>>529
定義時にはローカル変数にconstつけるのと同じ意味になる。

宣言においてはほんとに意味が無い。
宣言にconst付いてなくても、定義時につけることができる。
逆に宣言にconstがついてても、定義時につけないこともできる。
531526:04/09/12 03:56:23
>>530
解説サンクスです。

> 定義時にはローカル変数にconstつけるのと同じ意味になる。
確かにそのようです。

> 宣言にconst付いてなくても、定義時につけることができる。
> 逆に宣言にconstがついてても、定義時につけないこともできる。
試してみましたが、どっちもほんとにコンパイル通りますね。ちょっと驚き。
どっちも定義の方が有効になってるようです。

> 宣言においてはほんとに意味が無い。
なんでこういう仕様なんでしょうね?
普通に考えれば宣言と定義は一致してないとコンパイル通らなくていいはずなのに…

ヘッダファイルはいつもconst付けずに書いておき、
必要なら実装ファイルだけconstの付加/削除ができるってことですね。

ヘッダが変更されると一般にコンパイル時間が長くなるから
それを避けつつ変更できるような意図があるのかなぁ?
532デフォルトの名無しさん:04/09/12 04:43:41
どうせコピーなんでどうでもいいと思ってるとか
533デフォルトの名無しさん:04/09/12 12:32:29
>>531 過去レスもちっとは読もうな。>>501-
534デフォルトの名無しさん:04/09/21 21:02:43
const使うなら、コメント入れてほすぃ。自分では納得してても
他人が読むと「ハァ?」と考えてしまうことがあるだろう
535デフォルトの名無しさん:04/09/21 21:20:39
const int hoge = 0; // メシが3杯食えます
536デフォルトの名無しさん:04/09/21 21:52:22
const int ASAMESHI = 1;
const int HIRUMESHI = 2;
const int YUMESHI = 3;
537デフォルトの名無しさん:04/09/21 21:54:09
変数使うなら、コメント入れてほすぃ。自分では納得してても
他人が読むと「ハァ?」と考えてしまうことがあるだろう
538デフォルトの名無しさん:04/09/21 22:07:12
const int ASAMESHI = 1; //さて昨日見つけたバグ取りにかかるか。その前にメシだ。
const int HIRUMESHI = 2; //なぜだ?さっぱりわけわからん。気分転換にシだ。
const int YUMESHI = 3; //あそこのconstのせいで1日が消えちまった。気が付きゃメシの時間じゃないか。鬱ダシノウ。
539デフォルトの名無しさん:04/09/21 22:52:42
>>537
自明な変数ならコメントは要らないがな
540デフォルトの名無しさん:04/09/22 14:38:34
constが原因でハマる事例を知りたいんですが
どんなケース?
541デフォルトの名無しさん:04/09/22 15:07:10
const汚染でクラスのインターフェースを変更せざるを得なくなって激しくウザい事例
542デフォルトの名無しさん:04/09/22 15:47:17
const使わないなら、コメント入れてほすぃ。自分では納得してても
他人が読むと「ハァ?」と考えてしまうことがあるだろう

と、言いたい。
543デフォルトの名無しさん:04/09/22 16:30:00
>>540
>>458>>459のようなオーバーロードをした上、2つの関数のやることが全く違っていれば間違いなくはまる。
544デフォルトの名無しさん:04/09/22 17:11:12
>>543
スポポーン。そんな奴いねーよ。
545デフォルトの名無しさん:04/09/22 17:31:12
>>540
Java野郎が調子にのってC++始めて const ではまるケース。
546デフォルトの名無しさん:04/09/22 17:54:28
>>543
int i=1;

foo(i)
foo(1)

で挙動が変わるって事ですか?

それは正直、関数作った奴が悪いかと・・・
547デフォルトの名無しさん:04/09/22 19:54:53
オブジェクトを変更しないことを明示するなんて馬鹿げてるよ。
実際そんな馬鹿な仕様はまともなOOPLじゃ採用されてないし。
548デフォルトの名無しさん:04/09/22 20:03:53
Ruby >>>>>>>>>>>>>>>>>>>>>>>>>>>>>cおんst
549デフォルトの名無しさん:04/09/23 00:11:58
JavaはまともなOOPLじゃないですねそうですね。
550デフォルトの名無しさん:04/09/23 10:55:30
>>547
C++はまともなOOPLじゃないもん。
いや、良い意味で。
551s:04/09/23 12:46:17
おまいらこいつも大層美味ですよ!
ConstJava
ttp://pag.lcs.mit.edu/constjava/
552デフォルトの名無しさん:04/09/23 12:50:30
age
553デフォルトの名無しさん:04/09/23 21:07:22
食えねえな……。
554厨房:04/09/23 21:55:31
>>551
和訳きぼんぬ
555デフォルトの名無しさん:04/09/23 23:08:49
>>553
なんかスレが止まり出したよな…。
誰かconstの話キボンヌ
556デフォルトの名無しさん:04/09/24 13:45:42
まだ const をよく分かっていなかった時に
書こうとしてしまったコード。

template<typename T>
struct Container {
 void setItem (const T item) { /* 省 (゚Д゚) 略 */ }
};

Container<char *> container;
container.setItem("item"); // くそったれ!
557551:04/09/24 21:59:30
>>554
ちょっとだけ訳し始めているんだけどここでコピペして良いものか.
558551:04/09/24 22:37:04
C++のconstに加えて,概念的constが加わっているのがポイント.
というかそれをやらずしてconstをJavaに加える意味がないんだけど…

非staticのインナークラスのコンストラクタが constコンストラクタにできたり,
例外のthrowにconstを使えなかったり,
templateを使ってconst/非constバージョンのメソッドが使えたり,
constが付いてない既存ライブラリに後付けでconst指定できたり,いろいろ.
Javaとの協調も全然可能(らしい).

まぁ今のところ1プロジェクトに過ぎないんだけど, 既に実装があるのが良い.

#まだ試してないし,pdfも全部読んだわけではないのだけど,とりあえず紹介をば.
559デフォルトの名無しさん:04/09/25 22:26:57
>>558
概念的constってナーニ?
560551:04/09/25 23:28:18
う〜ん言葉として間違っているかもしんない.
よく言われるのは,
C++のconstメンバ関数内では,メンバ変数のビットを変更することはできないけど,
メンバ変数の参照先を変更することはできてしまう.
このようにC++では
概念的constとビットのconstがごちゃまぜになっていると言われます.確か.
>>321で言われているようなことが言いたかった.

ConstJavaでは,
constメソッドはフィールドを変更することもフィールドが参照している別のオブジェクトを変更することもできなくなっている.
前者は従来のJavaにおけるfinal, 後者はいわゆる概念的const.

561デフォルトの名無しさん:04/09/26 17:18:41
 
562デフォルトの名無しさん:04/09/26 18:42:19
スレをまったく読まずに560だけ見てレスします・・・。
はずしまくってたらゴメン。
よくわからんけど、メンバが指している先が自分に所属するとは限らないのだから一律読み取り専用にするのは const の理念とは違うと思う。
さらにオブジェクトはグローバル変数などの外部の要因によっても動作を変えるのだから、
インスタンス変数だけでなくて、ファイルスコープ変数、クラス変数、グローバル変数、引数などもすべて読み取り専用にしないと意味が無い。
そうなると、(概念的?)const メソッドは、外部に一切の変更を加えることができなくなるのだから、
それは const というよりは nosideeffect とかそんな感じだと思う。
563デフォルトの名無しさん:04/09/26 19:02:41
>>562
gcc の関数 attribute 、pure/const あたりがそれだな。
564551:04/09/27 15:05:03
>>562
>ファイルスコープ変数,…(略)…,などもすべて読み取り専用にしないと意味が無い。
あるオブジェクトを指す参照がconst参照しか存在しない場合,そのオブジェクトは不変であることが言語により保証される.らしい.(後述)
結局,そういう「限定的な」不変性の保証こそがconstの目的かと.
ConstJava does not place any guarantee on object immutability.
However, if only constant references to a given object exist (a constant reference is one through which an object cannot be mutated),
then the object is immutable.

>nosideeffect
constjavaが'const'キーワードを用いているのは単にC++からの類推であり,
意味的は確かに単語'const'(定数とか不変とか)とはちょっと違うモノかもしれない.

>>563
http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html
これか.すげー.知らなかった…(よく見ると>>296でも言われていた…)
565デフォルトの名無しさん:04/09/28 00:33:40
mutable や const_cast にもビクともしない真の const きぼん
566デフォルトの名無しさん:04/09/28 02:10:57
>>565
組み込みROM環境へいらっしゃいませ。
567デフォルトの名無しさん:04/09/28 06:10:57
ボスでよく見かけるところ
(俺が見かけるだけで実際は知らない)

NP > BH > 色 > Rev > CS > FL > Prima > その他
568デフォルトの名無しさん:04/09/28 09:49:42
void hoge( int& a )
{
a = 0;
}
は、コンパイラ側で
void hoge( int* a )
{
*a = 0;
}

に変換されて動作していると考えていいのでしょうか?
569デフォルトの名無しさん:04/09/28 09:50:53
>>568
多分そうだけど、絶対そうだとは言えない。
570デフォルトの名無しさん:04/09/28 10:19:34
const関係ないな。
571デフォルトの名無しさん:04/09/28 14:28:14
void hoge( int* a )
{
*a = 0;
}
は、コンパイラ側で
void hoge( int& a )
{
a = 0;
}

に変換されて動作していると考えていいのでしょうか?
572デフォルトの名無しさん:04/09/28 14:30:32
>>571
多分変換されないけど、絶対されないとは言えない。
573デフォルトの名無しさん:04/09/28 14:33:23
const関係ないな。
574デフォルトの名無しさん:04/09/28 19:02:03
どういう流れだよ
575デフォルトの名無しさん:04/09/29 00:07:41
ボスでよく見かけるところ
(俺が見かけるだけで実際は知らない)

NP > BH > 色 > Rev > CS > FL > Prima > その他
576デフォルトの名無しさん:04/10/23 22:23:31
C++ に const いらない。
うざいだけ。
577Rubysaikyou!!!!!!!!!!!!1:04/10/23 22:24:47
Ruby >>>>>>>>>>>>>>>>>>>>>>> const
578デフォルトの名無しさん:04/10/23 22:32:17
>>576
constを意識しない奴、ウゼー
579デフォルトの名無しさん:04/10/23 22:38:31
>>578
const うざいのはわかるけど、
const 使わないのをうざったがるのはどうして?
580デフォルトの名無しさん:04/10/23 22:48:18
Javaやってみろよ、const配列すら存在しないんだぞ?
Point とかのシンプルな値を返すときも参照返しだから書きかえられちゃう。
使いづらくってしょうがない。
581デフォルトの名無しさん:04/10/23 22:49:15
>>579
保守性
582デフォルトの名無しさん:04/10/23 23:14:57
>>579
ファイル名受け取る関数書かせたら引数の型が char* だったりするわけよ。
文字列リテラル渡したいだけで警告やらエラーやらをキャストで潰さないといけない。
583デフォルトの名無しさん:04/10/23 23:33:09
>582
そのまえに、その関数書いたバカをとっととシバキたおせよ。。。
584デフォルトの名無しさん:04/10/23 23:35:14
>>583
文盲?
それが「constを意識しない奴」だろ。
585デフォルトの名無しさん:04/10/24 09:18:20
>>580
それ、使い方が違ってるだけだろ。
リテラルオブジェクトへの直接の参照を書き換え不可の属性つけてやりとりするC++と違って、
リテラルオブジェクトとまったく同じ内容をコピーした別オブジェクトをやりとりするのがJava流、
オブジェクトへの操作と、オブジェクトの内容物の直接操作とを明確に区別してるだけのこと。

オブジェクトの物理的な居場所を剥き出しにしていて、const無しでは何をするにも危険な
(その分パフォーマンス的に有利な)C++とは、言語の位置づけ自体があまりにも違いすぎる。
Java使ってるなら、実体を返すか参照を返すかは区別せんと。
586デフォルトの名無しさん:04/10/24 10:21:30
>>585
Javaって実体を返せたっけ?
587デフォルトの名無しさん:04/10/24 13:47:48
むしろ実体への関節的な参照しか返せない。
…言い回しが面倒ちいなあ。
588デフォルトの名無しさん:04/10/24 14:21:55
ポインタを隠蔽して怖がりな人でも使えるようにした成果なんだからある意味仕方ないね。
589デフォルトの名無しさん:04/10/30 08:43:04
>>587
「実体への間接的な参照」ってことは、
「実体への直接的な参照」と
「実体への間接的な参照」があるってこと?

単に「参照」っていうのとはどう違うの?
590マイク ◆yrBrqfF1Ew :04/10/30 09:01:10
つまりオリジナルとポインタとリファレンスの三つが明解なC++が
良いと言う事だろ。
591デフォルトの名無しさん:04/10/30 13:42:54
>>590
C++も参照先を後から変更できるようにすれば良いんだけどね。
この馬鹿みたいな仕様で参照が使えない場面ってのが多いこと多いこと。
592デフォルトの名無しさん:04/10/30 14:46:50
nullも突っ込めないしな。もうアホかと。
593デフォルトの名無しさん:04/10/30 14:52:57
確かに
参照先を変えるのか参照先への代入なのか分からないから
そうなっちゃうんだろうけど
594デフォルトの名無しさん:04/10/30 14:54:29
もう仕様変更してもいいんじゃないの。
緩める方向への変更だから互換性も問題ないし。
595デフォルトの名無しさん:04/10/30 15:08:30
const string & const hogehoge
('A`)
596デフォルトの名無しさん:04/10/30 15:27:32
const廃止してvariable導入すればすべて解決。
597マイク ◆yrBrqfF1Ew :04/10/30 16:37:40
>>591
やたら気変わりするよりも一途な方がいいと思うが?
598デフォルトの名無しさん:04/10/30 17:13:38
class Hoge {
    Fuga& m_fuga;
public:
    Hoge() : m_fuga( 0 ) {
    }
    void SetFuga( Fuga& fuga ) {
        renew_reference( m_fuga, fuga );
    }
};

こんな感じの構文になるんだろうか。
599デフォルトの名無しさん:04/10/30 17:19:38
>>591
ポインタでいいじゃん
600デフォルトの名無しさん:04/10/30 17:29:12
boost::reference_wrapper
だな。

アホかと。
そんなもん標準で出来るようにしろと。
601デフォルトの名無しさん:04/10/30 17:33:29
>>597
たまには他の言語も使ってみたら
602デフォルトの名無しさん:04/10/30 19:04:16
Rubyとか。
603デフォルトの名無しさん:04/10/30 23:55:02
C++の参照は参照先が変わらないからいいんじゃないか。
変えたいんならポインタ使えばいいんだし。
604デフォルトの名無しさん:04/10/31 00:45:15
>C++の参照は参照先が変わらないからいいんじゃないか。
constポインタ使え
605デフォルトの名無しさん:04/10/31 01:00:36
>>604
お前、頭悪いだろ
606デフォルトの名無しさん:04/10/31 01:17:47
>>603
const参照とそうでない参照に分けるべきだと思う。
constポインタの場合、const_castで非constに出切るけど、参照の場合どうしようもない。
遅延初期化やserializationとかで困る。
607デフォルトの名無しさん:04/10/31 02:29:51
const string & const hogehoge = gehogeho;
にしろと?
608デフォルトの名無しさん:04/10/31 02:32:47
>>606
「const参照」「そうでない参照」の意味がわからん。
T const& と T& のことか?

「constポインタ」も曖昧でよくわからんな。
T* const のことか、 T const* のことか?
ん。あんた>604か?
609デフォルトの名無しさん:04/10/31 03:21:44
>>608
T& constとT&だろ。607にはちゃんと通じてるぞ。
T* cosntだろ。
T const*をconstポインタなんて呼ぶ文化があるのか?
604じゃないぞ。
610デフォルトの名無しさん:04/10/31 04:32:15
>>609
T* const なら、 const_cast したところで非constになるわけじゃないだろ。
コンパイラは騙せるが、書き込めば未定義動作だ。

> T const*をconstポインタなんて呼ぶ文化があるのか?
そんな文化は無いが、「constポインタ」でどちらかわかるのはエスパーだけ。
ちなみに、
http://www.google.co.jp/search?hl=ja&ie=UTF-8&q=%22const%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF%22

> 遅延初期化やserializationとかで困る。
C++ならおとなしく普通のポインタにしとけってことだろ。
611デフォルトの名無しさん:04/10/31 11:31:42
ようするに参照は糞
C++に他言語のまともな参照を要求する奴はアホ
612デフォルトの名無しさん:04/10/31 11:43:39
「constかどうか」
っていうのは、オブジェクトの属性にすべきなんだろうか。
どっちかって言うと、クラスの属性(そのクラスの全インスタンスの属性)で
あるべきではなかろうか。

613デフォルトの名無しさん:04/10/31 12:19:41
obj.SetReadOnly(true);
obj.SetX(5); // throw change_error_exception
614デフォルトの名無しさん:04/10/31 15:04:12
>>612
そのオブジェクトを指している変数の属性、だと思う。
615デフォルトの名無しさん:04/10/31 15:09:21
>>614
つまりそのオブジェクトを指している変数が変わる事で、
その、さされている側のオブジェクトがconstか非constかを
変えるべきである、って事?


複数の変数からオブジェクトが指されている時は、
どうなるのがイイと思う?
616デフォルトの名無しさん:04/10/31 15:17:24
理想としては
class ReadOnlyClass;
class WritableClass : public ReadOnlyClass;
のようになっていて、書き換えられる場面とられない場面でインターフェイスを使い分けるんだけど、
それはめんどくさいし、さらにそのクラスを継承した場合などで面倒なことになる。
const 変数は
暗黙のうちに、すべての型に対して
class A : public const_A;
のようなインターフェイスを提供している。
しかも A を継承した型 B に対しても自動的に const_B を提供してくれる。
617デフォルトの名無しさん:04/10/31 23:50:54
おまいらマルチパラダイムデザインも読んで味噌
618マイク ◆yrBrqfF1Ew :04/11/01 13:24:24
馬鹿の妄想よりも現実のC++の仕様が適切な解ということか?
619612:04/11/01 23:38:32
>>618
そだね。
620デフォルトの名無しさん:04/11/02 02:10:44
腐ってる、おかしい、穴だらけ、複雑すぎ、色々言われてるけど、
正直なところ、C++の弱点らしい弱点なんて微々たるものですよ。
だって、習熟しちゃえば間違わないし。
いままで散々言われてきた諸問題だって、インテリのおっちゃんたちが
喧々囂々と随分頭ひねって落ち着けてきたわけで(の割には不甲斐ない実装も
ちらほら観られるようだが、それはさておき)、漏れ的にはあとはもう
boostが隠し持ってる「こんなの標準が持ってなきゃ嘘だろ!」なテンプレートとかを
とっととC++標準にしてもらいたい。

欲を言うとJavaみたくimplementsでインターフェイスだけさっくり継承とか、
いつまでもヘッダ山ほどincludeさせんなとっととパッケージ化してimport一発で済ませるように
してくれとか色々ありはするますが

…これってひょっとしてDでつか?
621デフォルトの名無しさん:04/11/02 02:13:26
まさにRuby!!!!!!!!!!!!!!
622デフォルトの名無しさん:04/11/28 21:46:45
rullpo
623デフォルトの名無しさん:04/11/28 21:58:22
>622
ラッ
624デフォルトの名無しさん:04/11/28 23:55:02
何かよくわからんがワラタ
625デフォルトの名無しさん:05/01/18 18:32:23
かきあげ
626デフォルトの名無しさん:05/01/23 23:18:50
コメントにINとかOUTとか書いて、const使ってないやつはばか
627デフォルトの名無しさん:05/01/26 20:17:07
>>626
INでもOUTでもあるパラメータってのが存在するから、
「ばか」とも断定しづらいと思われ。


いや、まあ、constは使ってもらいたいが
628デフォルトの名無しさん:05/01/27 14:23:27
inだから、constつけておいたはいいが

古いCのライブラリに渡すので
中では結局const_castの嵐w
629デフォルトの名無しさん:05/01/27 15:40:16
>>628
const_castのカプセル化ということでそれはそれでいいじゃないか。
630デフォルトの名無しさん:05/03/08 20:08:13
const復権希望。
631デフォルトの名無しさん:05/03/10 23:24:16
>>630
復権っつーか、今やデフォでは?
632デフォルトの名無しさん:05/03/11 06:44:06
デフォなの?
じゃあ書換可能な変数は
writable int x;
とかやんなきゃいけないの?
633631:05/03/11 07:08:44
>>632
「変更しない変数にはconstつけるのが常識」って言う意味な。
(曖昧でスマソ)

あと、書き換え可能な変数につけるのは「mutable」。

634デフォルトの名無しさん:05/03/11 12:00:53
>>633
誤解を招く発言はやめろ(w
635デフォルトの名無しさん:05/03/11 12:41:51
これで誤解出来る方が凄いけどな
636デフォルトの名無しさん:05/03/11 15:45:01
Ruby >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> C++
637デフォルトの名無しさん:05/03/11 22:14:33
C++巛巛巛巛巛巛巛巛巛巛巛巛巛巛巛巛巛巛巛巛巛Ruby!
638デフォルトの名無しさん:05/03/12 13:27:39
Ruby なんてまったく存在価値なし
639デフォルトの名無しさん:05/03/12 13:57:25
そう評価してしまうお前の存在価値はない。
640デフォルトの名無しさん:05/03/12 14:23:57
いいねえそのヒス。
Runy持ち上げてる奴なんてこんなレベルだろうな。
641デフォルトの名無しさん:05/03/12 14:38:03
こんなレベルってどんなレベルだ?
642デフォルトの名無しさん:05/03/12 15:15:21
うbんこみたいなレベルだよばーか
643デフォルトの名無しさん:05/03/12 15:29:58
>>641
まぁ素直に考えて、言語の存在価値を提示してやり返すことができず、
その代替として人格批判に走ってしまう知能レベル及び人格レベルのことでは。
644デフォルトの名無しさん:05/03/12 15:42:22
C-Ruby
メジャーリーグ-草野球
645デフォルトの名無しさん:05/03/12 15:58:21
釣りが自作自演で必死なスレですね
646Rubyist!:05/03/12 16:00:02
自己顕示欲が旺盛で羨ましい限りですね。

お前と同じようにスルーされた奴が一人も居ないとでも思ってるのか?
何十何百何千という人間がこの世の至る所でスルー食らってる。
そしてその大半が、それは己の実力の無さと自覚もしている。
してねえのはテメエだけだよ、ガキが。
「よく頑張りましたね」で褒めてもらえるのは義務教育の学校の中だけだ。

大体何がチラシの裏だ。あんたが結局言いたいのは
「俺が先なんだ先にやったんだ俺を忘れるな俺を見てくれ見てくれ見てくれ」
たったこれだけだろうが。
そうやって他人を踏みつけにするようなことをして、あまつさえそいつをチラシの裏だ愚痴だと誤魔化して。
最低だね、反吐が出るよ。

チラシの裏だというなら、本物のチラシの裏にでも書いとけ。
人に見せんな。
647デフォルトの名無しさん:05/03/12 16:00:53
ま、こんなモンだよRuby厨なんて。
648デフォルトの名無しさん:05/03/12 16:02:01
>>643
>人格批判に走ってしまう知能レベル及び人格レベルのことでは。

目くそ鼻くそを笑うだな。
649デフォルトの名無しさん:05/03/12 16:03:15
ひ必死だなRuubyアンチども
650デフォルトの名無しさん:05/03/12 17:01:45
けっきょく出てこないRubyの存在価値。ふふふ。
651デフォルトの名無しさん:05/03/12 17:28:41
>>646
>自己顕示欲が旺盛で羨ましい限りですね。
とコテハンが申しております。
652デフォルトの名無しさん:05/03/15 18:33:13
おまえら、 const int 派? int const 派?
653デフォルトの名無しさん:05/03/15 18:36:59
int constの方が統一性があるのは分かるけど、
いつもなぜかconst intと書くな。
654デフォルトの名無しさん:05/03/15 18:48:25
char const* const* const argv だよな?
655デフォルトの名無しさん:05/03/15 18:51:17
int const 派。

こないだ、char const * const って書いたらキモイって言われた……_| ̄|○
そいつに言わせると、普通は、const char * らしい。
それじゃあ string が差してるポインタは変更できるじゃんなぁ?(´Д`)

static const char *string = "abc";
string = ""; // (´人`)チーン

static char const * const string = "abc";
string = ""; // (´ー`)ニンマリ
656デフォルトの名無しさん:05/03/15 18:53:37
>>654
それって規格上okだっけ?
char **const argv
なら良いと思うけど。
657#:05/03/15 18:57:26
658#:05/03/15 18:58:00
c
6591#:05/03/15 19:01:05
d
660デフォルトの名無しさん:05/03/15 19:31:42
>>654
ISO/IEC 9899:1999(C99)ではargvは書き換え可能な文字列で「なければならない」。
ISO/IEC 14882:1998(C++)は見つからない…誰か知らないか?
661デフォルトの名無しさん:05/03/15 19:36:38
>655
それは使い分ける意味があるだろ。
意味が一緒のconst char * と char const * のどっちで記述するかって事じゃないのか。
662デフォルトの名無しさん:05/03/15 19:37:02
文法はあってるっしょ

>>655
理解できてない気がする

static const char * const string = "abc";
string = ""; // (´ー`)ニンマリ

static char const * const string = "abc";
string = ""; // (´ー`)ニンマリ
663655:05/03/15 19:55:06
>>662
ポインタも const にするべき局面だったんだけど、そうしない馬鹿がいたよ、という話なのね。
理解できてないとか言う前に、笑いどころを理解してほしい(´Д`)
664デフォルトの名無しさん:05/03/15 19:58:20
途中で話変わってるがな
665デフォルトの名無しさん:05/03/15 20:20:54
自分がおもろいと思ったことを他人とも共有したかったんだって。
666デフォルトの名無しさん:05/03/15 20:22:52
>>664
何か問題でも?
667デフォルトの名無しさん:05/03/15 20:34:43
↑馬鹿注意
668662:05/03/15 20:35:17
>>663
ああなるほど

>>664
669デフォルトの名無しさん:05/03/15 21:38:59
で,お前ら結局メシ3杯食えたんか?
670デフォルトの名無しさん:05/03/16 08:34:10
int constなどとと書くキモいヤツは
iterator_constと書きたくてしょうがなかったりするんかね
ああ、キモ
671デフォルトの名無しさん:05/03/16 14:06:55
type const と const_iterator<type> は意味違うじゃん。阿呆?w
672デフォルトの名無しさん:05/03/16 15:08:56
>>671
唐突に誰も話題にしていないことを話して「阿呆?w」とか書かれても、
意味不明すぎてお前が阿呆に見えるばかりだよ。
673デフォルトの名無しさん:05/03/16 15:14:12
唐突に「キモ」とか言う奴も阿呆にしか見えないけどな。
674デフォルトの名無しさん:05/03/16 15:31:35
それは表現方法の問題でしょ。
誤読して「w」とか付けちゃってる奴のアホさとは比べものにならん。
675デフォルトの名無しさん:05/03/16 15:35:51
>>674
イイヨーイイヨー(・∀・)
676デフォルトの名無しさん:05/03/16 15:43:23
変にがんばってるな671
677デフォルトの名無しさん:05/03/16 22:52:31
boostを見るとシンタックスも流行だと分かる
流されてint const&♪
678デフォルトの名無しさん:2005/03/24(木) 22:56:25
int short unsigned const static i;
679デフォルトの名無しさん:2005/04/07(木) 20:28:59
うわキモっ!
680デフォルトの名無しさん:2005/04/07(木) 21:12:15
static const volatile unsigned short int scvusi;
681デフォルトの名無しさん:2005/04/07(木) 21:20:22
キモス
682デフォルトの名無しさん:2005/04/07(木) 21:27:20
まだautoが残ってる。
683デフォルトの名無しさん:2005/04/07(木) 21:56:27
pugya-
684デフォルトの名無しさん:2005/04/09(土) 10:45:42
const ore = DOUTEI;
685デフォルトの名無しさん:2005/04/09(土) 11:08:08
*(int *)&ore = 0;
686デフォルトの名無しさん:2005/04/09(土) 23:43:54
/*static*/ auto const volatile unsigned long long int acvulli = 0;

static と auto は共存できないんだったな orz
687デフォルトの名無しさん:2005/04/11(月) 14:15:22
それならregisterが使えないかな?
register auto const volatile unsigned long long int racvulli = 0;
688デフォルトの名無しさん:2005/04/11(月) 15:47:20
class ore {
public:
  ore():doutei(true) {};
private:
  const bool doutei;
};
689デフォルトの名無しさん:2005/04/11(月) 19:42:30
register, auto, static, typedefは「記憶クラス指定子」で、
ひとつしか現れてはいけない。
690デフォルトの名無しさん:2005/04/12(火) 05:19:44
autoがあるならglobalが無いのは変だよなあ
691デフォルトの名無しさん:2005/04/12(火) 07:49:24
restrictもつけられるんじゃない?
692デフォルトの名無しさん:2005/04/12(火) 22:02:50
>>690
#define global extern
ちなみにグローバル変数の定義時にもexternは付けられる。
693デフォルトの名無しさん:2005/04/13(水) 00:58:17
>692
どこかに一つ、extern無しの実体が無いと駄目だろ。
と思ったが、VC6でこれが通った。
extern int a = 0;
初期化が伴えばそれが定義と決定されると規定されているのか?
694デフォルトの名無しさん:2005/04/13(水) 13:42:13
>>693
C か C++ で過程が違う。結果は同じだけど。
初期化子があればいずれも最終的に定義になる
695デフォルトの名無しさん:2005/04/14(木) 00:46:17
このスレの連中はコンストって言いたい(発声したい)だけちゃうんか
696デフォルトの名無しさん:2005/04/14(木) 01:10:47
アンスコ
697デフォルトの名無しさん:2005/04/14(木) 12:00:34
トンスコ
698デフォルトの名無しさん:2005/04/15(金) 00:52:08
ttp://d.hatena.ne.jp/enra/20050414
「OKです」って、コレ、いいのか?
699デフォルトの名無しさん:2005/04/15(金) 01:26:28
うへえ、CODEやCONST DATAのセクションに書き込んでら
ウイルス対策で書き込み禁止になったら使えなくなるテクだな
700デフォルトの名無しさん:2005/04/15(金) 08:43:21
>>698
エエエェェェ(´Д`)ェェェエエエ
701デフォルトの名無しさん:2005/04/15(金) 11:45:41
つか、BREW って聞きしに勝る糞なのね…
702デフォルトの名無しさん:2005/04/25(月) 23:16:45
const使いな人=コニサー
703デフォルトの名無しさん:2005/04/25(月) 23:36:44
tはどこへ行った
704デフォルトの名無しさん:2005/04/26(火) 00:35:27
constist
705デフォルトの名無しさん:2005/04/26(火) 06:16:04
コンスタンチン君でいいよ
706デフォルトの名無しさん:2005/04/26(火) 10:43:27
>>705
それじゃアンチっぽい
707デフォルトの名無しさん:2005/04/29(金) 11:41:07
#define cosnt const
708デフォルトの名無しさん:2005/04/29(金) 14:36:41
sinst cosnt tannt
709デフォルトの名無しさん:2005/07/19(火) 00:35:52
保守してみる
710デフォルトの名無しさん:2005/07/19(火) 01:42:13
const int this_thread = conservative;
711デフォルトの名無しさん:2005/07/20(水) 22:55:25
革新してみる。
つうか、こんなに放置しても落ちないのか。
712709:2005/07/20(水) 23:40:47
>711
漏れもびっくりした。底の方には4/20日前後が最終書き込みのスレはいくつかあるけど。

まあ、漏れが常駐しているライトノベル板には最終書き込みが去年のスレとか
まだ残ってたりするわけですが……。
713デフォルトの名無しさん:2005/07/25(月) 11:43:24
シミュレーション板なんて全然落ちないけどな
714デフォルトの名無しさん:2005/09/02(金) 21:18:20
>713
2chギネスに載ってた最長レス間隔もシミュレーション板だっけ?
715デフォルトの名無しさん
//class hogeの中
public:
    const_reference operator [](size_type n) const
    {
        return p[n];
    }

    reference operator [](size_type n)
    {
        return const_cast<reference>(static_cast<const hoge&>(*this)[n]);
    }