○禿 校長先生。
0xになって記号の使い方が増えてますます気持ち悪い言語になったな
C++学園の人々:0a年春の巻 ○コンセプトさん(幽霊) かつての痕跡が校内から着々と消されつつあるのを草葉の影で眺めている。 彼女の居た14.10番教室はオバケが出るという噂で閉鎖中。 ○ラムダさん そろそろみんな制服の柄にも慣れたらしく、何も言われなくなってきた。 それどころか、関数さんがラムダさんとお揃いの服を着たいと言いだして物議を醸している。 ○右辺値参照さん ここへ来て急に彼女のせいで校則が変わることになったらしい。 彼女自身はすっかり学園に馴染みつつあるが、聴講生へのイジメが酷くならないか心配している。 ○拡張for文さん 服がクリーニングされそうな様子は一向にない。 屋上で「死にたい」と虚ろな目をして呟く様子がよく目撃されている。心配である。 ○constexprさん 従姉妹のconstさんと同じく地味な実力派。しかし意外と頭が悪く、単純な話しか理解できない。 「りかーしぶ」の振り回し方次第ではカオスになりかねないので、周りの大人のサポートが大事である。 なぜかstatic_assertさんとは仲が悪い。 ○type_traitsさん 最近ますます調子に乗って手が付けられなくなっている。 この間は「私だけで良かったんや!コンセプトなんか最初からいらんかったんや!」と言い放ち static_assertさんにドロップキックを食らった。 ○static_assertさん 暴走するtype_traitsさんとテンプレ部に振り回されて気苦労が絶えない。 姉貴はリリースコンパイルで逃げ出せるからいいよなーと愚痴りつつ仕事を真面目にこなす苦労人。
○initializer_listさん 「ねえねえ配列さん、なんでコンストラクタさんと仲良くしないの?」「新入生が来たら仲良くするよ!」 定番と化しつつあるこのやりとりの繰り返しで過剰な期待が勝手に高まりつつある。 本人はあまり何も考えていない。 ○テンプレート可変長引数さん テンプレ部にはすっかり馴染んだが、相変わらず一般生徒からは「あんた何の役に立つの?」 と受けが悪い。最近はもう面倒臭いのでいちいち説明するのをやめた。 ○autoさん 苦楽を共にしたregisterさんはついにD組に落第してしまった。 しかし一報を聞いたautoさんの反応は「ふーん、そう」という素っ気ないものだった。 昔の彼女はもういない。 ○decltypeさん 一人前の型としての振る舞いも身につけ、いよいよ活躍が期待される所だが、 服の違いで性格が変わる悪癖はまだ直っていない。 いつか必ず問題を起こすと一部の先生からマークされている。 ○ユーザー定義リテラルさん 「まだいたのか」と先生に暴言を吐かれ、体育館の陰で泣いていた。 ○nullptrさん 誰もNULLさんと見分けが付かないので、既にこっそり通学していると噂されている。 ○long longさん intさんに「ほら!あんたはこっちでしょ!」と間違えて上級生のクラスに連れて行かれた。 ○Raw String Literalさん 「お前全然Rawじゃねえじゃん」という状況は、トライグラフさんが譲る形で解決しつつある。 ちなみにトライグラフさんはしぶとく落第を免れ続けてるらしい。
○unique_ptrさん コンテナ部とも仲良くできます!あの女とは違うんです!と自分を売り込んでいるが、 みんなのauto_ptrさんのトラウマはなかなか払拭しきれず、苦戦している。 ○shared_ptrさん ライブラリ部が誇るご存じ優等生中の優等生。早く来てくれ。 ○unordered_map・unordered_setさん姉妹 名字はhashが良かったが、大人の事情で付けられなかった。 おかげでmap・setさん姉妹との違いをいちいち説明する羽目に。 ○Regular expressionさん Perl学園ではバカにされていたが、ここでは大歓迎。 満更ではないものの、学園の行く末に一抹の不安を抱いている。 ○Atomic operationさん 彼女と話していて業を煮やしたとある生徒が「こまけえこたぁいいんだよ!」と叫んで飛び出し 10分後に未定義動作にボコボコにされて帰ってきた。 ○threadさん 最大のライバルであるpthreadさんを蹴落とすべく日々努力しているが、 親友のラムダさんがpthreadさんとも親しくなりそうで焦っている。 ○System error supportさん ユーザー定義リテラルさんとよく一緒に弁当を食べている。 ○progress_displayたん System error supportさん達と一緒に弁当を食べようとしたら断られた。
○attributeさん 他の学校に、かならず一人はいる娘なので、学校側としても、しかたなく、入校させた。 服のセンスが、lambdaさんに負けず劣らず、相当悪い。 lambdaさんと、かぶっている帽子が、見る角度によっては、似ていることがあり、少々問題になっている。 lambdaさんとの区別は、帽子以外で判断すべきだと叫ばれている。 ○noexceptちゃん 入学試験の選考の最後になって、急に合格した赤ちゃん。 豪華にも、独自の制服を作ってもらった。 ○Inheriting Constructorさん 地味にできる娘。何で今までいなかったのか、不思議に思われている。 ○__VA_ARGS__さん クラス分けで、プリプロセッサ組に通うことになった娘。 プリプロセッサ組は、落ちこぼれだとも、最強だともいわれている、変わったクラス。 その外見はあまりにもブサイクだが、密かにファンもいるらしい。 ○exportさん 進級できなかった。 ○Exception specificationさん 進級できなかったが、彼女の産んだ、まだ一歳にもならない赤ちゃんが、いきなり入校してきた。
○type_indexさん type_info君と仲が良いらしい。 噂では、いくとこまでいったとかいってないとか。 ただし、開校前のクラス分けで離ればなれになってしまった。 ○System error supportさん いじめられて転校してきたらしい。 たぶん、どの学校でも相手にされない子。 ほとんどの学校には、学校独自の、もっとマシな子がいるし。 ○Tupleさん 博愛平等主義者。ほとんどのクラスメートと仲が良い。 ○Binder姉妹(bind1st,bind2nd) 落第。一応、まだ学校にはいる。 ○Function template bindさんと、Polymorphic function wrapperさん 二人とも、とても頭が良い。 なんでも、「ぶーすと」という一流の進学校から転校してきたらしい。 あまりに成績が良かったために偏差値を押し上げて、Binder姉妹を落第させる原因をつくった。 ○Time utilitieさん 2038年問題も3000年問題も大丈夫と豪語。 ○Compile-time rational arithmetic君 Time utilitieさんと仲が良いらしい。
> ○コンセプトさん(幽霊) 0xスレ1か2くらいで「直ぐに実装できる」って言われてたのになんでこんな酷い事になってんの?
○Blocksさん
○Blocksさん 遠く青森で林檎に囲まれて育ったラムダさんの親戚。帽子が特徴的。
なぜラムダ一族はおかしな帽子を被りたがるのか
attributeって、新しい記号を導入しちゃだめなのかな どうせtrigraphあるから、入力できない環境を作る事もないだろうし
○Blocksさん 青森の林檎農家が付属小学校への裏口入学を試みているラムダさんの親戚。 とても気難しく、隣の部屋に行くにも「ぶろっくこぴー」という赤絨毯を要求する箱入り娘。
もう2010年なんだから、そろそろC++ 1xでいいと思うんだが。
stroustorup先生が00年代に0xと言ってしまったので
C++1x 0 でも良かったか
スレタイはC++0x0Aになると思ってた
校長先生がC++0xのままでいくと言ったから C++0xのままでおk C++0x A あたりになるとは俺も思ったのだが まあどうでもいい
そろそろ#include棄てたいんだけどどうにかなるような話はなきや?
boost.ppが死ぬのでなきや
ラムダって関数ポインタにできないのか?
template関数でラップしてそのポインタを取ればできる
captureの無いλは関数へのポインタに変換出来るようにするという 提案があったと思うよ。
captureがないやつだけか まあそうだろうな
むしろPreprocessorはもっと勢力拡張すべき。
> ○__VA_ARGS__さん > クラス分けで、プリプロセッサ組に通うことになった娘。 > プリプロセッサ組は、落ちこぼれだとも、最強だともいわれている、変わったクラス。 > その外見はあまりにもブサイクだが、密かにファンもいるらしい。 そう、これだ。
__VA_ARGS__さんとテンプレート可変長引数さんとinitializer_listさんが組めば 空だって飛べる
vc++2010の対応が雑魚過ぎて困る
またVC6の頃みたいなバッドノウハウが累積される悪寒
まだC++0x自体が出来上がってないんだし仕方ないよ。 ドラフトをフライング実装してforのスコープ問題みたいなことがまた起こっても困るし。 個人で買いにくい価格設定になっているのはMSの良心かもしれない。
それならデフォルトではC++0xの機能をオフにして欲しかった
そもそも0x機能オフにできるの?
VC10はそもそも開発チーム自身が「新しいVC6だ」って言ってたし
SPなりhotfixなりで矢継ぎ早に修正してくれれば問題ないんじゃない? VC6は使われる時間が長すぎたからな とりあえずさっさと可変長引数テンプレートサポートしてくれ
MSは互換性を最優先させるから、 明らかに実装方法の誤りであっても次Ver.まで仕様で放置とか良くあるんだよな。
vc++2010って初期化リスト周りおかしくね?
初期化リストなんて面倒なこと言わずに{〜}をテンポラリな配列として扱えばよかったのに そうすればtemplate <class T, size_t N> void func(const T (&a)[N]);で受け取れるし コンパイル時にサイズもわかるし直にランダムアクセスもできる なにより組み込みなのにstd名前空間とか気持ち悪い現象が発生しない
parse上の問題でもあるんじゃない?
配列はないな サイズの取得が面倒くさい
組み込みなのにstd名前空間とか別に普通だよ new が失敗すりゃ std::bad_alloc 例外投げるし それを抑制する時に使うものも std::nothrow だし
std::initializer_list ってどう実装されてんの 引数を隠しローカル配列に入れておいて そのポインタを保持するとか?
前スレで紹介されてた
http://wiki.apache.org/stdcxx/C++0xCompilerSupport を見たところ、vc++2010はInitializer Lists対応してないね
確かにテンポラリな配列として扱えれば便利だよね
でも↓のような場合はstd::initializer_listがないと困る
// ヘッダファイル
void func(std::initializer_list<int> list);
// ソースファイル
void func(std::initializer_list<int> list) { ... }
と思ったけど仕様とか知らないからこれが可能なのかどうか
分からない
>>45 このケースなら薄いテンプレートで分離できなくも無い
使えないけど#include<initializer_list>は通るんだよな 中途半端なことやめて
std::initializer_list のクラステンプレート自体は実装してある でもそれだけなんだよな 中途半端やなあ
g++4.5.0も a[{1,2}] を解釈してくれない。 FCDには例示されてるけど、後で加筆されたものなのか
>>38 スイッチで切り替えられるようにしないのはどういうつもりなのかねえ。
03にしたけりゃユーザーが勝手に自分で03の範疇で書いてろよ、って事でね?
はあ?
>>51 VC10のC++0xの対応レベルで互換性が問題になるのはautoぐらいじゃね?
C++0xにはスマポ、正規表現、乱数とかいろいろあるから それ全部使えなくなるってのはちょっと… まあ、boostの使えば問題ないか
右辺値参照はすでに使いまくってるぜ
VC10でstd::tr1::shared_ptrとboost::shared_ptrがごっちゃになって困る。 using boost::shared_ptrして使っててstd::tr1::shared_ptrは使ってないつもりなのにstd::tr1::shared_ptrからboost::shared_ptrに変換できませんとか出る。何故なんだろう?
usingしなければよい
ナントカルックアップだろ
>>57 using namespace std;
なんてしてないよな?
どっかのヘッダでusingしてる悪寒
ヘッダでusingとかえんがちょにもほどがある
>>64 ヘッダのnamespace内でusingすることはあるけどなぁ
boost::tr1の真似して
ヘッダでusingするのは 名前を取り込みたい時であって 名前空間を省略したい時ではないぞ
あーおれ面倒だから using namespace std::string よくやるわすまん・・・
死刑
ローカルの関数スコープ以外のusingを禁止するコンパイルオプションはなぜ無いのか
auto f(int x) -> hoge { ・・・ } この書き方ってなんかイイコトあるんですか?
-> decltype が出来る、とか
template <typename T1, typename T2> auto add(const T1& a, const T2& b) -> decltype(a + b) { return a + b; } ができるからと言われるけど template <typename T1, typename T2> auto add(const T1& a, const T2& b) { return a + b; } を許してもらえるなら必要ないよね そもそも a + b を2度書かないといけないのが気に食わない
template <typename T1, typename T2> auto add(const T1& a, const T2& b) -> decltype(a + b);
auto hoge(fuga x) -> decltype(x + piyo()) { piyo y; return x + y; } この場合はこう書くの? けっこうメンドクセーな
template <typename T1, typename T2> auto add(const T1&, const T2&) -> decltype(std::declval<T1>() + std::declval<T2>());
struct Hoge { typedef int type ; type f() ; } ; というクラスがあった場合、このHoge::fの定義を書くのに、 従来の関数宣言の場合、 Hoge::type Hoge::f() { return 0 ; } 新しい関数宣言の場合、 auto Hoge::f() -> type { return 0 ; } 戻り値にクラス名の修飾がいらない。
まあそれなら便利な事もあるかな・・・ Hoge:: くらいなら auto -> 書くのと大差ないけど もっと長いと使えるかも
でもどっちかに統一しないと気持ち悪いよな
必要に応じて便利な方を使うしかない。 気持ちを最優先にしてもコンパイルに関係ないし。
コンパイルに関係ないなら気持ちは優先してもいいんじゃね?
それはない
>>70 class LongLongHogeHugaItteyoshiClass{
public:
typedef VeryVeryLongLongHawawaTypeName T;
T f();
};
auto LongLongHogeHugaItteyoshiClass::f() -> T
{
...
}
// LongLongHogeHugaItteyoshiClass.cpp #include "LongLongHogeHugaItteyoshiClass.h" typedef LongLongHogeHugaItteyoshiClass L; L::T L::f() { }
85 :
83 :2010/06/06(日) 18:40:00
ごめんなさい、すでに同じことが76に書かれてました。
>>84 と違って、
>>76 ,
>>83 のやり方だと
class 中の private な typedef にも使用可能だったはず…
privateなら好きに短い名前でtypedefすりゃええんやないの?
書くのがだるいというだけでtypedefを使うやつを俺は信用しない ていうか入力補完でいいじゃないか
べ、別にあんたに信用されようなんて思ってないんだからねっ!
typedefは必須だろう
書くのがだるいだけじゃないぞ 読み辛い
typedef使わずに素の宣言かいてたらクラスの変更とか困るだろ
C#でもmonoで書くと補完効かんぞ
std::mapの値とかvalue_typeをtypedefしてるから明確になるのに。
EDスクロールが早いから偽EDですね
ごめん誤爆・・・
知ってます
typedefないとtemplate成立しない
いやその理論はおかしい
テンプレート引数をtypedefしないと 外から使えないし
確かにtypedefだけではtemplateは成立しない。 typenameも必要だ。
>>82 最近の言語はみんな右に書くようになってるんだぜ?
例えば?
Fortran
>>103 C#はどうだっつんだ
てか、右でも左でもどっちでも変わらん
どちらが直感的とかない
右に書く言語は 従来の文法を拡張したら仕方なくそうなったって奴が多いな
なんだまたC#の人だったのか
日本語的には左 英語的には右
構文解析の都合を考えると左の方が便利
int a; int bb; int ccc; int dddd; a : int bb : int ccc : int dddd : int 下は揃わないな
inline namespaceって何者なんですか? 存在意義がいまいち不明なんですが・・・
つまり…どういう事だってばよ?
inline namespace だと?初耳だぜ。
理解できる部分だけ使えばいいのさ
118 :
デフォルトの名無しさん :2010/06/09(水) 12:32:56
数学的にどうのと言うなら = の意味の違いをどうにかせえ
数学的に何か問題あるのか?
数学的な厳密さを言うんなら副作用がある時点で
キャプチャなしのラムダをラップする関数ってどうやって作るの?
キャプチャなしラムダなら関数ポインタに暗黙変換できるからラッパなんか必要なし
次にお前は「おのれVC++2010」と言う
125 :
124 :2010/06/09(水) 23:20:46
ハッ!?
decltype(<<ラムダ式>>)::operator()のポインタ取れば?
自演だよなっ?
自演だとしても笑えたから許す
もうmailingは出ないのかしら
>>124 VC++ 2010がまだ追い付いていないだけ。
132 :
デフォルトの名無しさん :2010/06/11(金) 02:50:48
f(vector<int> &&); auto *x = new vector<int>; f(move(*x)); delete x; // ← このdeleteってなんか変なこと起こさないですか?
moveの後で*xに触ってるから未定義動作だな
デストラクタも呼べないのか? そんなまさか
やっぱりいるよ。
>>133 みたいな勘違いする奴が。
破壊的操作と未定義動作の区別がついて無いようだね。
X x; std::move(x); ができる以上、デストラクタは呼べるはず だからdeleteしても問題ないはず
やはり、std::moveなんて関数を標準で用意するから
>>133 みたいなバカがでるんだよ。
自前でstatic_castさせときゃいいんだよ。
139 :
デフォルトの名無しさん :2010/06/12(土) 08:08:29
たとえばこう書いて、RVO最適化可能ならムーブよりRVOが優先されるなんてあると嬉しいんですが。将来的にはありますか? Hoge func() { Hoge temp; temp.f1(); temp.f2(); return std::move(temp); }
今でもある。 その場合、 もしHogeがムーブコンストラクターを実装していなければ、 コピーコンストラクターが呼ばれる。 というか、最適化によって、コピーコンストラクターの呼び出しが省略される可能性もあるが。
お前実はRVOがなんだかわかってないだろ
ということは、 RVO可能->コピコンそのものが不用 RVO不可->コピコンまたはムーブ適用 ムーブコンストラクタがあってもRVO可能であればRVOが適用されるでいいのかな。 とりあえずstd::moveつけて置けば問題ないということでOK?
>>142 ごめん、読み間違えた。「ムーブより・・・優先」とみて条件反射でコピーコンストラクターだと思ってしまった。
>>143 よく考えたら、std::move通した時点でRVO可能なオブジェクトとコンパイラが認識できなくなる可能性があるね。
実験しないと分からないや
>>145 なぜ? rvalue referenceにキャストしているだけじゃないか。
ポインターならともかく。
というか何だその「実験」って。 未だにまともなC++コンパイラは存在しないんだぞ。 何を実験するというんだ。
そうか、まだなのか。 RVO_OR_MOVE()マクロ作って後からまとめて切り替えられるようにしておこうか。
>>146 キャストでコンパイラが自動変数って情報を落として最適化できなくなるんじゃないかなっと思った。
てかムーブよりRVOが優先されると嬉しいってどういうケースじゃろ
moveとかrvalueってさ、コンパイラに最適化のヒントを与える魔法のツールじゃないよね?
moveは最適化じゃないから、適用されるかどうかは確実に判断できる。 RVOは最適化だから確実な予測はできない。
>140 return std::move(temp); じゃなくて return temp; とだけ書いていれば良いのでは?
>>154 たとえばこれならほぼ確実にRVOがかかる。
return hoge(100);
だけど、こんな複雑な場合だとRVOがかからない場合がある。
hoge temp;
temp.func(100);//なんか操作する。
return temp;
RVOかからないなら次善策でムーブを使いたいなと。
>>155 return文で(コピーではなく)ムーブすることも決まっていることも決まっているから、
return temp;とだけ書いておけば、NRVOが適用されるならそれで、
適用されないならムーブで処理されることになるはず。
>155 いや,なのでそうとだけ書いておきさえすれば (1)コンパイラが RVO を適用できるならする (2)hoge が move constructor を持っているならば return で move を使う (3)コピー というのを上から順に適用していって可能なものを採用すると思います. (2) は, return temp; という文においては temp が自動変数なので, まず temp を自動的に右辺値として取り扱おうとするはずだからです.
158 :
124 :2010/06/12(土) 19:18:10
hoge func() { const hoge h; return h; } moveにならなくて不愉快
>>158 それはconstなオブジェクトからムーブできない話であって、また別の話。
ムーブは元オブジェクトを破壊してよいことを前提としているので、
constなオブジェクトはすなわち破壊できないので、そこからムーブできないということ。
可能な限りconst付ける教とムーブセマンティクスは本質的に相性が良くない。
それは当然・・・
関数の戻り値として返すときは特別扱いして欲しいってことか
>>157 丁寧な回答ありがとうです。
returnはmoveを使うで理解しました。
c++0xは思ったより気が利いてるなと感心したり
VCのSP1はまだか
>>164 あほか
まだVC2010そのものが店頭で売ってない
ダウンロード販売のみ
SP1はいくらなんでもその後だろう
あるとしたら店頭に並んでるものに既にSP1が適用してあるとか
そういう場合くらいしか
世の中には発売前にパッチが出たりするソフトがあるんだよ
というかVS2010は、よくあれでリリースしたなという出来なんだが。 IDEからしてクソすぎるし。
>>167 さっさとてめえの化石PCを窓から投げ捨てろ
遅いといってるわけではなさそうだが。完成度が低いというなら分かる。
遅い上に完成度が低い
2005proのIDEから2010eeのC++コンパイラが呼び出せたらベストなんだが
そりゃ抱き合わせですよ 独占ですから
RVOやNRVOが出来たかどうか調べるにはどうしたらいいのだろうか・・・難しい・・・・・・・・
コピーコンストラクタでログ録ってそれが無視されてたら最適化されたとみていいんじゃねーか?
LLVM の C++ (の開発版)で、オプションつけると RVO/NRVO 対象に できたかどうかわかるよ
inlineみたいにされたか出るコマンドはGCCにはないですか?
副作用があるのに勝手に消えられるのも困るよな
RVOのような動作が変わる最適化はコンパイルメーカの独断ではできないから、あえて規格上で許してるんでしょう。 規格上許しているんだから、コピコン省かれて困る設計のほうがまずいんではないか?
んだ
VC++EE2010で #include <iostream> struct Hoge { static volatile int count_; Hoge() { } Hoge(const Hoge & hoge) { ++count_; } }; volatile int Hoge::count_ = 0; Hoge test() { return Hoge(); } int main(void) { Hoge h(test()), g(test()); std::cout << Hoge::count_ << std::endl; return 0; } ってやってみたけどcount_はゼロだったぜ volatile無視かよ
>>181 RVOでコピコンがそのもの省略されてるんだから、countのvolatileは無関係だろ。
RVOが行われる場合、 コピコンが影響するのはアクセス制限くらいやで
じゃあ人類にRVO最適化をコードから阻止する手段は残されていないのですか?
>>184 こんなの通してreturnに渡したらかからなくなったことがあったような気がする
template<class T>
inline T& stop(T& a)
{
returan a;
}
RVOが効いて困るコードを書く方が問題があるぞ。バグの温床じゃないか?直したほうがいいよ。
RVOが問題なるケースが思いつかない
きっと常人には理解もできない状況なのだろう 理解したくもないが
gccが__m128用のコピーコンストラクタ書いているのにスタックに積んで4バイトずつコピーするのはRVOのせいだったのか。 RVOうぜー。
RVO,NRVO > move()>無し だからね。 (RVO OR 無し) あるいは (move()) だから非常に困るね。
>>189 もっと整理して書けよw
プログラムもそうなのか?
>>188 コピーしているならRVOじゃないよね。コピーそのもの存在を無くすのがRVOなのに。
どんなコピーコンストラクタかいてるの?
可変長テンプレートつかった可変長引数の関数って引数は再帰で取り出すしかないんですか? 再帰はオーバーヘッドがありそうで嫌です
じゃあ使うな
>>194 ちょっと意味わからないから
コードを2chのこのスレッドに投稿してくれる??
「2chのこのスレッドに」とわざわざ言うのは 「this->」みたいなもんか
const Hoge &は左辺・右辺とわず受け取れるけど 非constで左辺・右辺両方を受け取れるにはどうすればいいの?
マクロで仮引数の型だけ違う同じ内容の函数を書き出す
非constの右辺値受け取ってどうするんだろう
move
おいこらConceptはいつ入るんだ
Conceptはみんなの心の中に生き続けているよ
C++1xにご期待ください。
>>200 だけど、自分の書いたソースコードの中で使用例見つけてしまった。
コンテナから本体を書き換えることのできる部分コンテナを返す関数を
別の関数に参照渡しする場合だな。
具体的にはOpenCVのcv::Matの部分配列(ROI)なんだが。
VC++の非標準の拡張によって右辺値が非constの左辺値参照に置き換えられてたみたいだ。
コンパイルレベルをあげたら警告が出た。
>>198 右辺値を非constで左辺値のように受けるのは危険だから受けられないようになっている。そのための&&だ。
まずそれが必要か考え直したほうがいい。
すみません質問ですが #include <iostream> auto main() -> int { []{ std::cout << "hello, world\n"; }(); } 以下の部分は何を意味してるのでしょうか? main() -> int
推論不能時の戻り値
「返却値」だろうが
それ俺がν速で書いた奴じゃないかw
そんなクソ短いコードなんてとっくの昔に誰かが書いてるわ
212 :
207 :2010/06/19(土) 02:26:00
ありがとうございます
戻り値を後ろに書く構文ってだけ
>>213 auto func(int x)->decltype(hoge(x)){return hoge(x);}
これをこんな風にかけると二回同じ式を書かなくてすむんだけど
auto func(int x)->hoge(x);
-> の後ろに直接式書くとかキモいことしなくても 普通にこれでええやん auto func(int x) { return hoge(x); } ラムダではできるのに普通の関数ではできない仕様なのは ヘッダに書く関数や単一ファイル内で使う関数でないと意味がないからか? と思ったけど、これやりたいのって大体関数テンプレートだから できてもいいように思える
Unified Function Syntaxにも戻り型推測提案してこい
>>215 そんな記述もできるの?
{}のなかを評価しないと戻りの型が決まらないんでできないと思ってた。コンパイラは大変だなあ
もしこの関数がメンバー関数の場合{}の中は前方参照不可とか制約無いのかな?
もうUnified function syntaxのことは忘れようぜ… とっくにrejectされてんだから
auto func = [](int x){return hoge(x);}; なら行ける けどテンプレートにできんのよね
>>218 VC++2010で使えるけど、これは先走ったわけか
auto hoge() -> int { return 0; } // OK
int main() { return hoge(); }
もう仕事に0x使い始めてるところなんてあるの?
>>221 unified function syntaxってのはこれ
[]main()->int{ return 0; }
>>217 ラムダでは戻り値型の推測はできるので
普通の関数でもできないわけじゃないはずだ
普通の関数は多値returnができるけど
ラムダではできないという違いも
普通の関数での戻り値推測がない点に関係あるのだろうか?
ラムダは実装もすぐに書くから返り値がわかるけど 普通の関数やメンバ関数はヘッダとソースが分かれてるかもしれない
分かれてない場合には使えるじゃない、と
>>226 > 普通の関数は多値returnができるけど
C++ って多値返せないだろ, どういう意味だ?
文脈からみて一個の関数内にreturnが複数個あるって事じゃね?
231 :
188 :2010/06/19(土) 10:22:53
>>191-192 gcc 4.4.0で起きたからレポートしようと思っていたらgcc 4.5.0で直ってた
>>229 std::initializer_list を引数に取るコンストラクタを持つクラスが戻り値の型になってる場合、
return { 0, 1 }; みたいにできる
for_each(v, [](auto &x){ return x+=10; }); みたいな引数の型を推論してくれるようなラムダってないの?ないの?の?
だからboost::lambdaがなくならないのさ
いい加減多次元の動的配列をサポートしろよ
>>235 イラネ、ライブラリで対応できる。
そういう言語サポートが必要なのは拡張能力の乏しい言語だけ
どうしてBoost.MultiArrayを標準化しなかった。
標準にするにはマニアックすぎたんじゃないか? 第二水準標準ライブラリとか作って採用して欲しい。
ライブラリでできるからといって組み込みで必要ないというなら initializer_listもライブラリでいいんだな?
240 :
188 :2010/06/19(土) 19:25:21
>>236 いや処理系の問題だが、ICCなんかループが深くなると添字の計算をループの外に出さなくなって途端に遅くなる問題とかあるぞ。
m x nの二次元配列aで直線的にアクセスする場合、
for ( int j = 0; j < n; ++j ) {
for ( int i = 0; i < m; ++i ) {
// a[i+j*m] を読み出してなんか処理
}}
で通常j*mはfor(i)の外に移動される。
でもこのループが同じ関数内でも4重5重とネストが深い時に外に出されなくなった。
これが三次元配列、四次元配列となるにつれ、
a[i+j*m+k*m*n+l*m*n*o ...]と式が複雑になっていって、コンパイラを混乱させる。
なので多次元配列が組み込みとして存在すれば、最適化の推論は簡単になる。
>>240 そういうのって、部分配列で次元数を減少させてループを書いたりするんじゃね?
いくら組み込みでも多次元の添え字をランダムアクセスで渡せば最適化できないだろう。結局同じテクニックが必要だと思うんだ。
>>240 処理系の所為なら同じ問題が起きるだけじゃね?
多次元配列って実装が一種類じゃないんだよね。 C配列、FORTRAN配列、row-first、collumn-first 使用目的に応じて実装できるライブラリが適してると思うんだよ。 行列にしても、帯行列、三角、スパース行列、など行列の特性に応じた格納方法があるし。 組み込み多次元配列を用意したところで適用できなければメリットは小さいと思うよ。
245 :
188 :2010/06/19(土) 21:13:45
>>244 その理論だとFORTRANに多次元配列がある説明になっていないぞ。
確かに疎行列のような特殊なものはライブラリで補うしかない。
row-first、column-firstも行列積の概念から来ているだけ。
C言語的に必要なのはa(i, j)があった時にメモリが隣接しているのはどっちの添字かという事だけ。縦も横も無い。
あとCの静的多次元配列は「ポインタの配列」または「ポインタのポインタ」と矛盾しないようにあんな順序になっているだけ。
>>235 は単に基本となる配列を動的多次元にしてくれって言っているだけでしょ。
そしてその意見には
>>240 的観点から賛同する。
いい加減自己主張やめて名前欄消せ
可変長テンプレート引数を利用すれば std::vectorからの0オーバーヘッドを保ちつつ作れそうか
例え次元数固定でもテンプレートで作っちゃうと、毎回愚直にアドレス計算されるよ。
特殊化すりゃいいだけじゃん
特殊化してもj*mをループの外に移動出来ないでしょ。
多次元配列が欲しいんじゃなくて最適化して欲しいだけじゃないか
boostの多次元配列はコンパイル時間長いし、そもそもboost禁止の場合もある 組み込みの多次元配列が有ってうれしいことはあっても困ることはない
組み込みの多次元配列がなくて困ると言う声がほとんどない以上、入る事はないな。
利便性の向上でもあり、最適化のヒントにもなるツール。 言語の歴史から言えば多分RVOよかよっぽど基本的な話。
困ることが無いから入れるという理屈では入ることは無い。 実現方法がたくさんあると、ライブラリ間でのデータの受け渡しに支障が出る。
NULL終端じゃなくてサイズ+データの基本データ型があるだけでも汎用性高いんだけどね。 FORTRANはデータだけでもコンパイラに多次元配列である事を伝えることが出来る。 Cっぽく書くと void func(int n, int m, int array[m][n]) {} ってな感じ。
C++ で数値計算しようと思わないからいらね > 多次元配列
initializer_listで受け取った引数は連続領域にある前提で書いていいの?
多次元配列はライブラリでできるのがC++ 組み込みじゃないなと嫌っていう人はFORTRANを遣えば良いってだけの話。
はいはい数値計算数値計算。 そういう本質が分からん奴に限ってWin32APIで絵を表示しようとしたときに SetPixelを使って、「遅い」とか言い出すんだよなあ。
必要度 concept>多次元配列 コンセプトは必要。マジ欲しい。
>>255 そうそう
規格で統一すれば異なるライブラリ間で多次元配列を簡単にやり取りできるのにね
>258 一旦配列に確保されたかのように扱われるから OK のはず。end() も begin() + size() になってる。
最適化のためのキーワード(や、それに代わるもの)がほしいって話なら… registerが肥やしに変わった以上、マジそれがないと実現不可能とかじゃないと追加は難しいんじゃないかな 上の例だと「ネストが深くても最適化してくんない?」ってIntelにリクエストすればいいだけだし
これ以上議論する気はないけれど、配列に追加のキーワードはいらないだろ。 そんなこと言うならRVOとかmoveとか口にするなよ。 initializer_listだってなんだって、多くのものは利便性の向上をメインとして 更に最適化の機会向上も兼ね備えているんだよ。
これ以上議論する気はないけれどと言っておきながら議論ふっかける男の人って。。。
自分の言いたいことは言うけど、反論されるのは怖いからやめてください。
initializer_listって配列の代わりに使えるよな もっと一般化できそうだが
反論は怖くない。そこから得られるものがあればいい。 あまり続けると、他の話題を出したい人が話に割り込めなくなるのが怖いだけだ。
無様な言い訳をする男の人って軟弱でステキ!
ユーザー定義リテラルなんかよりインクルードガードが欲しかったな
途中まで #pragma once が規格に残っていたのにいつのまにか消えたのは何でだろう
gcc と vc は #pragma once 使えるから規格になくてもいいや
LLVMのCLangも大きな派閥になってくると思う。 ConceptGCCの中の人がC++サポートをやってるし。
>>272 インクルードガードだと、インクルードが循環参照するとコンパイルされなくてエラーになるのが便利。
#pragma oneceだとヘッダの参照関係が循環してもコンパイルが通ってしまって不便、危険。
??
循環参照を気にしなくてもいいように#pragma once使うんじゃないの?
#pragma once の問題はハードリンクをどう扱うか程度じゃなかったっけか? そしてそれが致命傷
インクルードガード内の循環参照は重複してインクルードされないだろ
>>280 インクルードされないから循環参照をエラーとして検出できる。
例を出せ もちろんちゃんとコンパイルして期待した動作をすることを確かめてからな
// a.h #ifndef a_h #define a_h #include "b.h" struct A {}; #endif a_h // b.h #ifndef b_h #define b_h #include "a.h" // 循環参照 struct B {}; #endif b_h // a.cpp #include <ostream> #include "a.h" int main() { std::cout << sizeof(A) << ' ' << sizeof(B) << std::endl; } 問題なくコンパイルできる
循環参照が#pragma onceにしただけで解消されるとか どんなファンタジーなんだ
std::pair を template<typename U, typename... Args> pair(U&&, Args&&...) で構築するとして pair<int, int> p(1); の second は zero-initialized と決まってるんでしょうか
インクルードガードを書けば循環参照が検出できるなんて どんなファンタジーなんだ
#includeは参照じゃないだろ。 ファイルに埋め込まれるから自己埋め込みになる。
>インクルードガードだと、インクルードが循環参照するとコンパイルされなくてエラーになるのが便利。 そろそろサンプルぷりーず
#errorで自分でやるんじゃないの
#includeはただの埋め込みだとなんどいったら(ry
>285 そのコンストラクタは N3092 には無いです.
クラスの循環参照とごっちゃになってる人がいる?
このスレはC++上級者の中でも更に次の規格について議論する人たちの集まりかと思っていたら、 上を目指すどころかコンパイラの仕組みも理解してない人多くね?
クラスの循環参照って何? コンパイラの仕組みとか以前というか 自分で勝手に意味を決めてるやつが多いのかな?
VCのpragma onceて、初見のソースにつき一回しか参照っていうか取り込みされないと思ってたのだがちがったのか?
違わない
だよ〜ね。
しかし、ハードリンクが絡むと状況は複雑になる パスが全く違っても同じ実体を指している事があるけど、 それも検出せなあかんのん? と
iノード番号でわかるだろ
内容が全く同じソースなら弾けばいいんじゃないのかしら? たとえ実態が別々でも
環境によっては色々面倒な話が出てくるから、規格から外されたわけだ。
環境ごとの面倒な話を統一するための規格じゃないのか 根性ねえなぁ
めんどくせぇ
>>291 ソデスカ… orz
では、pair に限らず (U&&, Args&&... args) の args が省略された場合
fundamental type を forward<Args>(args)... で構築した場合
zero-initialized と期待していいのでしょうか
>>302 ディレクトリ操作すら規格にない言語だから仕方がない
かろうじてディレクトリに関するerrnoがあるくらいだ
306 :
デフォルトの名無しさん :2010/06/23(水) 21:34:56
禿は # で始まらない include を夢見てたようだが
ソースファイルをコンパイルしたら 外部に公開できる宣言をまとめたファイルが自動的に作られて、 それをimportするような感じになってくれればなあと思う
むしろ、ソースファイルを指定したら、 そこから必要な宣言集を構築してくれるような仕組みの方がいい。 わざわざ分ける必要はない。 いまどきヘッダーファイルなんて時代じゃねーだろ。
それはC++/CLI
>>308 C++でそれやると現実的なコンパイル速度にならない気がする
コンパイルとリンクが別になってるのが既に時代遅れ
313 :
デフォルトの名無しさん :2010/06/24(木) 08:39:24
暗号化がデフォじゃないのもね
> 暗号化がデフォじゃないのもね お前のプログラムがリバースエンジニアリングの対象になるわけねーだろ 思い上がるな
このスレはC++上級者の中でも更に次の規格について議論する人たちの集まりかと思っていたら、 上を目指すどころかコンピューターの仕組みも理解してない人多くね?
流石コンピューターおばあちゃんは言うことが違う
bool operator && (function<bool ()> reval); こんな感じで右辺の評価が自動で関数オブジェクトになりshort circuitが可能になると思っていたのに自分でlambdaにしないと駄目なのか
initializer_listってどうなってんだ? typedefしたらコンパイル通らなくなるし、配列のように振る舞うって聞いたのに代入したらベクターみたいに動作するし、[]の中に{}突っ込んでもエラー出るしでわけわからん
VC++2010か まだ対応してないぞ 定義はあるけど
VC++2010は色々と残念
>>320 IDEは2008の改良でいいのにあちこち退化して残念
いやgcc4.5.0の話です
-std=c++0x(gnu++0x)付けた?
もちろん
gccの実装はまだ完全じゃないからな。 typedefはワケ分からんが、operator []は、まだ実装してない。 だいたい、initializer_listは配列のように振舞わない、どこで聞いたんだそんな話。
typedefが動かないバグは上がってないな。 報告しておいたら?
いや、配列のようにってのはここできいたんだがw
ネット上に出回る情報が全部正しい訳じゃないなんていつものこと
まあ、リスト初期化の構文自体は、素の配列や構造体を初期化する文法を、 ユーザー定義のクラスでも使えるようにしようというものだから、 その辺が伝聞が変化したのかも。 初期化リスト(initializer list)は、あたかも配列を初期化するように振舞う ↓ std::initializer_listは、あたかも配列のように振舞う
ラムダからinitializer listをreturnできるようにしてくださいよぉ
これじゃだめか? []() -> std::vector<int> { std::vector<int> v = {1,2,3} ; return v ; } ;
auto foo = []() -> std::vector<int> { return { 1, 2, 3 }; }; みたいにしたいんだけどねえ 普通の関数ではできるのに 何で禁止したんだろ 実装が難しいの?
ていうかそれでいいのなら、こういうことはできるがな。 [] { return std::vector<int>{1,2,3} ; } ;
returnが多いと面倒くさいけど 仕方がないのかねえ
おれ的には右辺値参照と可変長テンプレートとラムダだけで十分だった
conceptほしかった…
conceptは犠牲になったのだ……
0xの犠牲にな
最適化の為だけのキーワードが云々ほざいてる奴もいたが、俺はconstexprが好きだぜ。
それって最適化か?
332のコードは通るでしょ
constexprはTMPの道具でしょ
<unordered_set>で余分なバケツを削る方法はありませんか? (<vector>でのいわゆるswap技法に対応するもの)
ん?swap技法使えないのか?
こんな感じです。(コピペできなくてすみません) unordered_set<int> s; for (i in 0...100) s.insert(i); cout << s.bucket_count() << endl; unordered_set<int>(s).swap(s); cout << s.bucket_count() << endl; > 199 > 199
unordered_set<int>(s).swap(s); これだとsと同じコンテナとsの中身を交換という形になってしまうぞ。 vectorで同じことをしてもreserveされた領域は小さくなるだろうが、サイズは変わらない。
>>346 バケツとアイテム数は同じにはならないだろ。
1000個挿入して900個消してからやってみ
unordered_set<int>().swap(s);
s.empty()
>>350 これはひどい
まあこのメンバ関数名もどうかと思うけど
わたし350だけど349したらs.empty()が真になるって言いたかったんだけど
353 :
350 :2010/06/27(日) 11:29:12
みんなひどい!もうしらない!
やりたいことが伝わってなかったようで、申し訳ないです。 そもそもの目的は、 rehash(n)でバケツの数がn「以上」になってしまうのを ちょうどnにしたいのです。
clearしても真にはなるでしょ、と
356 :
354 :2010/06/27(日) 11:33:58
unordered_set<myclass> になっていて、ハッシュ関数もユーザ定義しています。
358 :
354 :2010/06/27(日) 11:38:24
>>357 やっぱ無理なんですか・・・。
別の目的に使うhackをしてたんだけど。残念です。
我流unodered_setを作ろう
>>359 そうだな、自分で作れば理由もわかるしな
361 :
354 :2010/06/27(日) 11:43:51
ウェブ上で複数の人が「バケツへのアクセスが提供されてる理由が不明」、 と言っておられるようですが、歴史的な経緯って誰か知りませんか?
362 :
354 :2010/06/27(日) 11:44:51
>> 359,360 CSの人じゃないので、 お手軽hackに走っちゃうんですよね・・・。 精進します。
>>361 どういう意図で言ってるのか解らんのでurl貼って。
365 :
354 :2010/06/27(日) 11:55:12
まあアクセスしたいこともあるだろう ハッシュの性能評価とか
>>365 >bucketの個数や容量、使用量を取得するメンバがあり、さらには、あるキーがどのbucketに属するかを取得するメンバもある
これだけ解ればハッシュをチューニングできるし、バケツにアクセスする必要ないだろう。
バケツへのアクセスを規定したら実装方法に制限を加えることになるから妥当じゃないのか。
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1456.html の G. Bucket Interface より
It's also useful to expose the bucket structure, for two reasons.
First, it lets users investigate how well their hash function performs: it lets them test how evenly elements are distributed within buckets,
and to look at the elements within a bucket to see if they have any common properties.
Second, if the iterators have an underlying segmented structure (as they do in existing singly linked list implementations),
algorithms that exploit that structure, with an explicit nested loop, can be more efficient than algorithms that view the elements as a flat range.
だそうだ
369 :
354 :2010/06/27(日) 20:34:24
おぉ、ということは変な使い方しても怒られないのね。 わざわざ調べていただいて、ありがとうございました。
私も354ではありませんが勉強になりました。ありがとうございました。
俺漏れも
タプルはinit_listで初期化できないみたいですが、 こんなのを my_tuple<int,int> tup={1,2}; 自分でつくるとしたらどうするのがいいんですかね? サイズの型チェックできなそうだし・・・。
型が全て同じという前提なら作れるだろうけど そうでなければboost::anyで包むしか
てすと
>>372 ctor がexplicit でなければ uniform initialization が使えるはず
可変長テンプレートでコンストラクタ書いて{}で初期化したいって場合に 違う型が混ざってれば問題ないんだけどすべて同じ型だとイニリスになって定義してないとコンパイルエラー 納得いかないわ
>>376 もしあなたの処理系で std::tuple<int,int,int> t = {1, 2, 3}; でコンパイルエラーがでないなら、
あなたが何か勘違いしてるのだろう。
どういうこった? 素直に書くとこうなるが。 struct C { template < typename... Types > C(Types... args) { } } ; int main() { C c = {1,2,3} ; } 当然これは通る。 通らなければお前のコンパイラがマヌケなだけだが。
gcc5.0.0だが通らないぞ まじマヌケだなこの糞コンパイラ
Comeau.Computing の Comeau C/C++ では通らないの?
gcc 5.0。 未来からタイムマシーンでやってきたのか?
gcc4.5.0ね間違えた
まあ、gccはあてにならんな。
ちなみに、4.6だと
>>378 は通る。
384 :
デフォルトの名無しさん :2010/06/30(水) 11:03:48
テンプレート関数のテンプレートで型を指定した場合にテンプレートの型が ムーブコンストラクターを実装している場合に、その型のオブジェクトを返すとき戻り値をmove( );で返して その他の場合はNRVOを使うために普通に返す。 なんて事ができる?
普通に戻り値の型を非参照にして、return std::move(t)すりゃいいだろ。 それでRVOできなけりゃ、そりゃコンパイラがバカなだけだ。
戻り値の型を非参照にするって???
そのまんまの意味だよ。 参照ではないprvalueで返せばいい。 class C {} ; C f() { C c ; return std::move(c) ; } int main() { C c = f() ;// まともなコンパイラならRVOできる }
悪いけど全く意味が分からない。 日本語でおk
正解かどうかはともかく言ってる意味は分かるだろ… 理解できる言語が日本語だけだと厳しいかもしれないがw
>>384 そもそも return move(....); がいらないだろ。 return ...; で同じことになるんじゃなかったっけ?
それもそうだ。
それは最適化じゃなくて必ずそうなるって決まりなの?
C++の標準規格には、必ず最適化せよという決まりは、まずないぞ。 Schemeの規格に、必ず末尾再帰の最適化をせよ、とあるのは、Schemeにとっては絶対に外せない根本的な概念だからなんだろうな。 ちなみに、return文の式は、コピーかムーブコンストラクターかのオーバーロード解決のためならば、 rvalueとして扱ってもいいことになっている。
「扱ってもいい」って何だよ… returnの式はソースだけじゃtaxon決まらないのかよ 相変わらず気持ち悪い仕様だな
気持ち悪い=個人的に理解不能 ってだけの話
そうかなぁ lvalueかrvalueかがunspecifiedな第4のvalue taxonが隠れてるって事じゃないの? キモイよ
return move(....); がいらないってどういうことだよ? 無かったら一時オブジェクトにコピーするときコピーコンストラクターが 呼ばれてしまうとおもうがwwwww
だから、rvalueとして扱っていいってことだよ。 return文の式は、関数の戻り値の型に変換される。 これが大前提の挙動。 このとき、コピー、ムーブコンストラクターの呼び出しを省略してもよい これが、RVO(Return Value Optimization)と呼ばれるもの。 このとき、コピーかムーブかのコンストラクターのオーバーロード解決のために、 式をrvalueとみなしてもよい。(つまり、ムーブコンストラクターを呼べる) どんな式でもというわけにはいかんが、どうせreturn文が評価されるということは、 その関数のブロックスコープを抜けるということであって、ローカル変数の寿命は終わる。 もし、式がローカル変数のlvalueだとしたら、ムーブしたっていいだろ、どうせすぐ死ぬんだから。
誰か規格をもってきてくれ……
まあ移植した時にどうなるかわからんのだし明示的に書けばいいじゃん
>398 「rvalue とみなしてもよい」ではなくて「まず rvalue とみなす」では?
N3092 の 12.8/34 には 「ある基準が満たされたときに "when certain criteria are met", RVO に相当する最適化をやっても良い "an implementation is allowed to...". ごにょごにょ. で, copy/move の省略は以下の状況で許される (...is permitted in the following circumstances). (以下,その条件が列挙されている)」 と書いてあって, N3092 の 12.8/35 には 「copy の省略のための基準(★)が満たされていて "when the criteria for elision of a copy operation are met" コピーされようとしているオブジェクトが lvalue なら, コピーのためのコンストラクタを選択するオーバーロード解決は "overload resolution to select the constructor for the copy" まずコピーされようとしているそのオブジェクトが rvalue であるかのように実行される "is first performed as if the object were designated by an rvalue".」 ★の基準は 12.8/34 に記述されている条件を指していると思われます. で, 12.8/34 に列挙されている条件のうちの第1の bullet に書いてある内容から, 「return 文の式が,関数の戻り値型と (cv-qualification の違いを無視して) 同じ型の non-volatile の自動オブジェクトの名前である場合」という条件の場合, 12.8/35 に書いてある挙動 (まず右辺値として扱ってみる) が発動すると思います. (12.8/35 に書いてある挙動が発動することが許される,ではない)
え〜っと,つまりまとめると, 12.8/34 には「ある条件下でコピーの省略 (いわゆる RVO) を行うことが*許される*.この条件の1つに return 文に指定された式が戻り値と同じ型の左辺値自動オブジェクトの場合がある.」と書いてあって, 12.8/35 には「12.8/34 に示された条件下では,コピー元をまず右辺値とみなせ. (みなしても良い,ではない)」 と書いてあるように読めますがどうでしょうか?
おお本当だ。 コピーが省略出来る場合で、しかも省略しない場合は、まずムーブコンストラクターを優先的に使うんだな。
RVOもしらん馬鹿が一人紛れ込んだか
そんなことで勝ち誇れるなんて幸せですね もしかしてオランダ在住ですか?
難しいな。例えば可視性が絡んだらどうなるんだろ? 例えば下のauto_ptr-ライクなコードはムーブコンストラクタ可能ならコンパイルできて、 コピーコンストラクタが呼ばれたり、RVOが採用される場合はコンパイルエラーになるの? ちなみにVS2010だとムーブコンストラクタが呼ばれる。 class Foo { public: Foo() : ptr_(new int(3)) { std::clog << "construct Foo()\n"; } ~Foo() { std::clog << "destruct Foo()\n"; delete ptr_; } Foo(Foo&& rhs) : ptr_(rhs.ptr_) { std::clog << "construct Foo() by move\n"; rhs.ptr_ = 0; } private: Foo(const Foo& rhs); Foo& operator=(const Foo&); private: int* ptr_; }; Foo createFoo() { Foo f; return f; }
まずコピーが可能でなけりゃRVOは採用されない ムーブが出来ない式ならコンパイルエラー つーかunique_ptrに触れてみそ
規格なんてどうでも良い、 GCCで出来るか出来ないか それだけが問題だろ。
規格も GCC もどうでも良い、 VCで出来るか出来ないか それだけが問題さ。
実装なんていらない。 規格がどうなっているか。 それだけが問題なり。
実装がすべて。 委員会のメンバーは実装者/組織を代表している。 いかに自分たちの実装(に基づく規格)を通すか。 いかに自分たち(の実装に)不利な規格を落とすか。 だから日本からの提案は無いし(たまに)あっても通らない。 わかったかな?
つまらんレスだな わかるか?
確かにお前のレスはつまらん
うわホントにつまらんこの人
initializer listはともかく、コンセプトなしのrange based forなんてまったく骨抜きで使い物になんねーよ。
c++2xにご期待ください
>>418 そこでrange仮想クラスを継承ですよ、継承。
今のところwindows環境でつかえる一番できのいい0xコンパイラーってどれですか?
知るかボケ
知っとけよアホ
自分で作れ。 もちろんconceptsも実装してだ。
C++0x以前に解決法があるのかもしれませんが、 template <class T, class P> class Base; を次のように継承したい場合に template <class T, template <class> class Q> class Derived: Base<T,Q<T>> { typedef Base<T,Q<T>> base; } 長ったるいBase<T,Q<T>>を2度書くことになってしまいます。 うまい解決策はないでしょうか?
つ define
マクロはなしで・・・。
手元のModern C++を眺めるかぎり、 #define TLIST_2(T1,T2) Typelist<T1, TLIST_1(T2)> とかしてますね・・・。 やっぱ無理か。
0xなら、usingで別名つければ少しは短くなりそうな。
template <class T, template <class> class Q, typename U = Q<T>> class Derived2: Base<T, U> { typedef Base<T, U> base; }; とか
>>430 その手を使うなら↓ここまでやったほうがよくね?
template <class T, template <class> class Q, class BaseT = Base<T,Q<T> > >
class Derived: BaseT {
typedef BaseT base;
};
>>425 template <class T, template <class> class Q>
class Derived: Base<T,Q<T>> {
typedef Derived::Base base;
}
というかこれ、gccがおかしいんじゃねーかな。
Derivedにとって、Baseはinjected-class-nameだろ。
あーすまん、この場合、BaseはDependant Nameじゃないな。そりゃ無理だ。
434 :
425 :2010/07/08(木) 13:58:25
各種ありがとうございました。
C++0xの0xってどういう意味?
xには0からF
一桁目だと誰が決めたのだろう そう20x0だったんだよ!
時が未来へ進むと誰が決めたんだ
時代が
多分次ぎはc++0y
>>436 F でけりがつくんかい?
ハゲの論調だと 9 で終わりそうもないので 0...F みたいな感じだったが ...
バージョンの数字か何かが続くってことなのかな? 数字の範囲を超えそうなら36進数にでもして 桁を増やしていけばいいのに、なんで0xなんてわざわざつけたんだろう
今となっては信じ難いことだが 本当は2007年に完成する予定だったんだ
C++98だって、延びに延びていたがな。
xが何になろうと、右辺値参照とLambdaとautoが既に実装されてるから気にしない。一休み一休み
うんこドドンパ
わざとですね分かります
イニリスの長さをコンパイル時に知りたいんだけどconstexprが実装されるのを待つしかないのか
コンパイル時に分かるわけねーだろ。
アトリビュートの構文に違和感を覚えたのは俺だけでいい
どんな構文でもマクロよりはましだと悟った キレイなC++なんてC++じゃないんだ!
パーサーが解析でないような構文を違和感のある構文っていうんだよ。
元々汚かったC++の文法規則がattribute-specifierだらけになってますます小汚くなった
C++0xの解説の本ありませんか?
本屋からC++関連の本が綺麗に消えたな C++0xに向けて調整中か?
本屋にはウェブ書籍のコーナーにAjax本、Java本コーナーにJavaScript本があるって印象しかないなあ
C++自体が消えたって可能性は考えないのか
もういいかげん拡張はあきらめて新しい言語作ればいいのに
そして生まれた言語の数々。
いっぱいあんだろ。 そのうちJAVAでOS作るのが当たり前の時代とかもきちゃったりするぞ。
D最終形態にはあらゆる言語がひれ伏すぞ。
アルティメットD・・・ 仮面ライダーにいたよ、そんな敵
eclipseでOS作ればJAVA使ったことになるのさ
JavaでOSってどうやって書くの? ブートローダで真っ先にJVM呼ぶの? ハードウェアアクセスを全部JVM様にお願いして仲介してもらうの? カーネルのメモリまで全部GCに支配されてんの? オエッ
Javaのバイトコードをネイティブにデコードするプロセッサなんだろう。きっと。
ちょっと待ってほしい もし仮にPCに電源投入すると Javaインタープリターが起ち上るとするならば、 これもまたJavaOSと名乗ることを許されるのではないだろうか
そのインタプリタはCで書かれてるんですね わかります
JavaをJavaで書けるようになってからだね。
Visual C++はVisual C++で作成されています。 ってVC++6.0のスプラッシュに書いてあった
>>469 SingularityっていうC#(の拡張言語)で書かれた似たようなOSの場合は
WindowsでいうHALはC++で書かれていてそれ以外の部分がC#になってた
>>470 なんか10年前に話だけは聞いたことあるけどどうなったんだろうなアレ
富士通とか携帯用プロセッサに乗っけてたな?
>>476 今のTexas InstrumentのARMプロセッサは多くが"Java Acceleration"
という機能を謳っているけど何なんだろう?
?
480 :
478 :2010/07/17(土) 20:14:33
D&E読んでるけどなんで既にconceptあるの
何も最近新しく出来た概念ってわけじゃない。 当時からアイディアはあったんだよ。 ちなみに、今とまったく同じautoは、すでに1982年に、C with Classesの一部として、禿によって実装されていた。 残念ながら、Cとの互換性の問題で、消さなければならなかったっけれど。
昔はCで組んでたけど、autoなんて使った記憶ないなあ。 消さなきゃ良かったのに。
元のautoを有効利用したことがある奴いるの?
registerでないことを明示したい時に使う void foo(){ int x; &x; } こんなxを勝手にレジスタに置いてポインタが取れないと癇癪を起こしてたのさ 昔々のコンパイラは
487 :
485 :2010/07/17(土) 21:41:08
元のauto、ね。 タイプ量を増やす以外の役割は??
>>486 あ、ごめん、
> 昔々のコンパイラは
ね。
ってことは、途中で規格が改訂されて省略可能になったわけか。
ありがとうございます。
昔のコンパイラはレジスタ配置すら人力だったのか……
絶望した。 std::vector<int>& Get(){ return vec;//クラス内で宣言済み } 上のようなメソッドが有って、 auto vec = hoge.Get(); ってやったら、ムーブかコピーだった。参照で受け取れるとおもったんだが。 で、結局 auto& vec = hoge.Get() ってやったら意図通りになった。@VC10
>>490 の通りが普通だと思ってたんだけど、
規格上の動作はVC10と違うの?
auto var = exp;はexpの評価されたTypeがvarの宣言/定義に使用される。 たとえhoge.Get()が参照を返したとしても、式中では参照のついたstd::vector<int>&ではなくstd::vector<int>として評価される。 これは0xに関係なく今の時点でもそう。 どうしてもと言いたければboost::refを使って式中の評価を参照修飾にする必要がある。
decltype
decltype((hoge.Get())) vec = hoge.Get()
#define BOOST_AUTO(E, F) decltype(E) F = E;
497 :
490 :2010/07/18(日) 12:31:26
返信ありがと〜。
>>491 いやー、俺の勘違いのようですよ。
戻り値の型を評価されるんだと思ってたので、&取られるのは気づきにくいなーと。
>>492 詳細ありがとう。理解が深まって助かるよ。
厳密にboostのようなものが必要だったわけじゃないからいいんだけど、
知らなかったら、コストかかるわ、バグの元になってるわで、自分的には不味かったんだ。
>>493 decltype先生はタイプ量増えるから難しいね。
おっとっと。
>>494 最近はムーブされるから多少マシになったけど、その前はRVOか全コピーだからマズーって感じ??
>>495-496 decltype先生は用途がむずかしいね。
decltype で書かなきゃいけないの? と思ってfcd読み返したら
auto& みたいな書き方でOKだったじゃないか。
>>495 みたいなのは、&で返ってくるときは&で、
値で返ってくるときは値で受け取りたいときに使うってことだね。
500 :
490 :2010/07/18(日) 14:00:35
autoって互換性無くさなくてよくね? 今までだと auto hoge h; これからは auto h = hoge(); だから別に構文は被ってないじゃん
型を省略したらintとかそんなのなかったっけ?
それはあまりにもフリーダム
まあ、いまだに残ってるんだよな。 unsigned x = 0 ;// unsigned int
いや、unsigned x; は型名省略じゃない
処理系の一番手ごろな型えらぶんだっけ??
いや、unsigned/signed は unsigned int/signed int の別名だから。
signedなんて予約語あったっけ?
あるよ
static x; みたいな例の方がわかりやすい。
関数定義の戻り値省略とかも
513 :
207 :2010/07/19(月) 21:30:00
すみません gccで現在コンパイルがC++0xとして行われているか判別する方法はないでしょうか 事前定義マクロのようなものはないでしょうか?
auto a = test();とかやってみる
515 :
デフォルトの名無しさん :2010/07/19(月) 21:43:07
>>514 すみません.言葉が足りませんでした.
コード中で0xに対応していればstd::threadを
対応してなければboost::threadを使う
といった使い方をしたいのです.
#if __cplusplus > 199711L でいいと思う
ありがとうございます. 試してみます.
__cplusplus In C++0x the macro __cplusplus will be set to a value that differs from (is greater than) the current 199711L. とのことで #if __cplusplus != 199711L 少し不安ですがでいけました.ありがとうございました.
#if __cplusplus < 199711L // 0x #else // boost #endif まだ少し不安ですがこうしてみました. バージョンが新しいほど値が小さくなるのでしょうか gcc version 4.4.3 で試しています.
greater than
>>521 なるほど
__cplusplusの値を見てみたのですが
msvcでは199711Lでした
gcc version 4.4.3では1でした
まだ制定されていないからでしょうか.
FAQにあるように,199711L以外としか決まってないのでしょうか
しょうが無いので1の場合は0xと見なして処理してみます.
いやgccは昔からずっと1にしてるぞ
なるほどそうだったのですか とりあえずgccはコンパイラのバージョンを見て決めることにしてみます
gcc の場合 __GXX_EXPERIMENTAL_CXX0X__
_HAS_CPP0X とか、もうね(ry
_から始まるからだめ
コンパイラが定義する分にはいいんじゃね?
書いてて気持ち悪いからやだ
VS2010にThreadがないんだけど、まだ入ってないん?
あん…
ぱん…
まん・・・
あたらしい質問です C++0xでは例外指定が消えただの何だのと聞いたんですが、 try-catchが消えるってことですか?
finallyは欲しいところ
>>537 throwができなくなるor非推奨になるって認識で良いんでしょうか
>>539 関数の定義の際に、
int hoge() throw(なんとか) { ... }
という書式があったんだよ。
541 :
デフォルトの名無しさん :2010/08/03(火) 08:57:07
0xだとライブラリレベルのスコープガード実装で満足できる気がする
544 :
デフォルトの名無しさん :2010/08/03(火) 13:57:44
0を返すテンプレート関数 zero() を作るとします。 template< typename result_type > result_type zero() { return result_type(0); } そして、関数テンプレートの特殊化で、それぞれの型にあわせたzero()をt作るとします。 template< > int zero< int >() { return 0; } // 例1 template< > float zero< float >() { return 0.0f; } // 例2 template< > double zero< double >() { return 0.0; } // 例3 ある特殊な数を表す special_value< value_type > クラスがあり、 special_value< int > や special_value< char > など無数に定義されているとします。 この special_value< value_type > に対し、zero() を定義したいのですが、 現状だと special_value の具体的なクラスひとつひとつに特殊化を定義しなければならず、大変手間です。 template< > special_value< int > zero< special_value< int > >() { return 0; } // <-これが無数に必要 出来れば、特殊化は special_value< value_type > ひとつだけにして、 尚且つ、zero()の呼び出しも簡素な形にしたいのです。 special_value< int > i = zero(); // <-理想 special_value< int > i = zero< special_value< int > >(); // <-現実 少なくともこれ以上、呼び出し文を複雑にしたくない 関数テンプレートの特殊化は少なく、呼び出しは簡素な良い方法はないでしょうか?
>544 struct { template <typename T> T operator()() const { return 0; } } const zero = {};
>>545 どうもコンパイルエラーがでる…
struct {
template <typename T> operator T () const { return 0; }
} const zero = {};
として、
special_value<int> i = zero;
だと、OK だった。
>>545 >>546 結局、
struct zero {
template <typename T> operator T () const { return 0; }
};
とすれば、
special_value< int > i = zero();
で、いける。
>>545-547 検証した結果、その方法で全てOKでした。
使わせてもらいます。ありがとうございました。
>>542 これは素晴らしい。惚れた
C++にこの構文を入れるプリプロセッサとかないものか
Boost.ScopeExit
>実際ソースコード上で視覚的に大きく離れてしまします。 素晴らしい日本語だな
boostだと表記が長ったらしくて嫌
最近のboostはPP厨すぎて付いていけない
test
本の話が出てこないな
魔導書? 面白かったけど、なんか話題のネタになるようなのあったっけ?
このスレに出入りするような生粋にとっては特に目新しい情報なかったでしょ
ゲームスレでも開いたのかと思った
Variadic Templatesはケーススタディが微妙だった
0xおわったな・・・
始まってすらいねーよ
まずCスタイルキャストの廃止をだなry
>>562 そんな事したら、だれも使わなくなると思うんだな
じゃあ、Cスタイルのキャストをstatic_castと同じ意味にすれば
互換性パラノイアのC++に何を求めてるんだ
キャストは長たらしくて面倒なんだよなあ
Cスタイルキャスト便利だけど周知のとおりなんでも変形できちゃうからねぇ・・・。 最近はC++スタイルを使うように心がけてる。
signed ⇔ unsigned signed ⇔ 浮動小数点数 共にリテラルなのに処理が違うのは変だと思う。
569 :
デフォルトの名無しさん :2010/08/21(土) 01:27:27
この言語は次世代を担う最強言語たりえるの?
最強かは知らないが、もともと使ってた人にはステップアップできるいい改良。 根っこは腐ってしまったが、周辺は良好。
拡張メンバ関数を導入するべきだ .h class hoge { int x; public: int y; void print_xy(); }; .cpp namespace { inline private void hoge::print_x() { cout << x << endl; } // privateならprivateに触れる。ただしprivateの拡張メンバか非拡張のメンバからしか呼べない inline public void hoge::print_y() { cout << y << endl; } // publicならpublicにしか触れない、どこからでも呼べる } void hoge::print_xy() { print_x(); print_y(); } こんな感じで 仕様変えたい時にメンバ増やしてもコンパイル依存性は変わらないから便利だろ ヘッダもすっきりするしな
>>569 最強というか、そもそもC++が必要な領域では対抗できる言語が無いからね
Dはまだまだだし
>>573 それ何年も前の本(ピアソンとか)で
そんなもん非メンバ関数で実装すればいいだろ
って書かれてた気がする
コンパイル依存性を変えないなら仮想関数に適用できなくなるし
しかもその例だと非拡張メンバ関数から拡張メンバ関数を呼び出してて
なお一層気持ち悪い
非メンバ関数じゃprivateメンバーが見えないじゃん なにかコードを追加しようとしたときに そのコードがprivateメンバーを使ってて さらに同じコードをなんども書く必要がある場合は 外部関数じゃできないんだからメンバー関数追加するじゃない普通 でもそのクラスをインクルードしてるファイルが死ぬほどたくさんあったらどうすんのよ
>>576 設計がおかしいからリファクタリングしろ。
それと、ここは 0x のスレだから、提案されてもない機能の話題はスレ違い。
俺の考えた最強言語の話は自分のブログでやってくれ。
>>576 そんな簡単にprivateに侵入されたらプライバシーもクソもないじゃない
#include <utility> template <class... X> class Hoge { public: void invoke(X... x) { func(x...); } template <class... Y> void t_invoke(Y &&... y) { func(std::forward<Y>(y)...); } private: void func(X... x) { } }; t_invokeのほうは無駄なく転送してくれそうなのですがinvokeのほうだとコピーコストが発生して困ります かといって引数の型をX &&...やconst X &..に変更すると引数によってコンパイルエラーが出ます そして引数の参照性やconst性の組み合わせを網羅してオーバーロードするのも可変長では無理ですしできても現実的じゃありません 何とかしてinvokeのほうでも無駄なコピーのない転送を実現したいんですがどうすればいいんでしょうか? 最終的にinvokeを関数ポインタにしたいのでどうしてもtemplateは使えないんです
>>579 const X &で困るのってどんなとき?
581 :
579 :2010/08/21(土) 21:16:43
あ、すいません自己解決しました
可変長引数にも普通にメタ関数使ってtypename foo<X>::type...って感じでコンパイル通るんですね
>>580 Hoge<int &>とかHoge<int &&>だとconst参照ではエラーがでますね
constexperでCRCやMD5とか計算できるようにならないかな? 30バイトぐらいでもかまいません
CRCならこんな感じで書けそう 確認はしていない const uint64_t key = 0x104C11DB7; constexpr uint32_t CRC32_subsub(uint64_t n, int b) { return b==0 ? n : CRC32_sub( ( (n & 0x8000000000000000) ? n ^ (key<<31) : n) << 1, b-1); } constexpr uint32_t CRC32_sub(uint32_t head, uint32_t tail[], int tlen) { return tlen==0 ? head : CRC32_sub( CRC32_subsub( ((uint64_t)*head<<32) | tail[0], 32), &tail[1], tlen-1); } constexpr uint32_t CRC32(uint32_t input[], int len) { return CRC32_sub(input[0], &input[1], len-1); }
今更だけど64ビット定数は嫌がらせのように長いな・・・
585 :
デフォルトの名無しさん :2010/08/22(日) 21:42:25
4096bit とかどうしようか
桁数間違えそうだわ
それもあってのconstexprなのかも
0x8000 0000 0000 0000 こう書けばよい
デバッガで追ってる時にポインタが 0x000000000485c77a とか表示されるの拷問
590 :
デフォルトの名無しさん :2010/08/22(日) 22:29:19
>>588 0x\
8000\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
8000\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
やだよこんなの
CRCってこうやって計算してるのかぁ
ipv6みたいな短縮記法を使いたくなってくるよね。 0x80::01で0x8000000000000001になる的な。
ユーザ定義リテラルの出番か
void関数でreturnでvoidを返せるようにしましょうよ。
return ; de ok
>>594 現行の規格でも関数テンプレートならいけたはず。
何か具体的に通らなくて困ってるコードでもあるの?
>>490 この問題ですんごいはまってた。
そうか、仕様だったのか・・・
>>597 コンパイラ上にだけ存在する常にvoidしか入らない0バイト長の型とか?
理論上の存在意義は分からんでもないが現実に嬉しいかというと微妙だなぁ
void 型の値があることになったら、末尾呼出を常に return func(); と書けるな。
void型値が存在すれば加減算とかが発生しない限り代入や比較は可能で構わないわけだから void型の返値を受け取ってvoid型の変数に格納してvoid型の引数を取る関数に渡すとか有りか 最終的に評価が発生するところだけvoid型で特殊化できるという意味で理論上の適応はあるな 誰が得するのか知らんが
sizeofが0の型はカオスを引き起こすからダメです
あー、0除算で死んだりするのか・・・。
コンパイル時定数なんだからソレは問題に成らんでしょ
コンパイル時定数を普通の変数に代入して使うこともあるわけで、問題なくなるわけがない。
関数は必ず、void func(int)だろうと何だろうと 何かしらの値を返す、 ただ、void型の場合はその値に意味なんてないですよ ってんだと俺は勝手に思っていた。 そして、コンパイラがその値を参照しようとすると コンパイルエラーになるようにしているんだと思っていた。
perl病
void func2(); void func() { return func2(); } これができるとテンプレートとかでvoidだけ例外処理する必要なくなるので嬉しい。
それはもう出来るんじゃなかった?
早く言えよ! すこしコードがすっきりしたぜ。
611 :
デフォルトの名無しさん :2010/08/28(土) 22:08:27
http://www.open-std.org/jtc1/sc22/wg21/ > News 2010-08-28: The 2010-07 post Rapperswil mailing is available
> News 2010-08-28: The C++ Standard Core Language Issues List (Revision 72) is available
最新ドラフトは N3126 ね。 > Added new issues 1091, 1092, ... and 1173. 3週間ほどで追加されすぎw
相変わらずJPのNBコメントは質が低いのう……
813さんが質の高いコメントを出していただけないため。
えらいロングパス出したな
ゴールラインを割りましたので スローインから再開です
617 :
デフォルトの名無しさん :2010/08/30(月) 19:43:12
結局継承関係もalignasも予約語になるんだな attributeとは一体何だったのか
禿って蔑称?愛称?敬称?
その全て
日本の在日禿=蔑称 Bなんとかの禿=尊称
std::unique_ptr<Type []>の知名度が低すぎる ~~
配列生成しても適当に開放してくれるの??
そうだよ。 boost::scoped_array 相当だね。
おぉー。オペレータがどういう感じになってるか興味あるかも。 delete[] で両方開放できるんだっけ??
delete[] しないためのものだろうに。何言ってるの?
あるぅぇ??
default_deleteがT[]で特殊化されてるからか なるほど
struct Hoge { void swap(Hoge& rhs) {} Hoge& operator=(Hoge&& rhs) { swap(rhs); } 上記のコードのように、右辺値参照である rhs を 非const参照を受け取る swap に渡すことは仕様的に合法なのでしょうか?
>>632 何か変なこと言っている??
> やっぱC++標準化委員会のひとはいうことが違うな
つまんね くだらない記事はるなよ
規格で許されていることをバグとして報告する輩にはもっと▽してやれ
C++相談室に0xに関する質問したので来て答えてくれませんか? どうせ暇でしょ。
>>637-639 つまり、これが C++0x なら通るのか?って話だね。
#include <cassert>
struct Boo
{
Boo() : b(111) {}
int b;
};
struct Foo
{
Boo boo;
int f;
};
Foo foo[100] = {0};
int main()
{
for (int i = 0; i < 100; ++i)
{
assert(foo[i].f == 0);
assert(foo[i].boo.b == 111);
}
return 0;
}
cygwin の g++ 4.3 だと、まだ initializer list の対応が入ってなくて試せない。
>>640 それは通らない。
なぜならば、Fooの最初のデータメンバーであるBooは、0では初期化できない。
Boo boo = 0 ; // エラー
よって、次の文もエラーとなる
Foo foo[100] = {0}; // エラー
これなら通る
Foo foo[100] = { } ;
>>642 > MSVCは、「'A::b' : non-aggregates cannot be initialized with initializer list」などというエラーを吐く。
> これは、規格上間違っている。
これ、 C++2003 では正しいエラーだよね。
> この分では、C++0xの初期化リストの対応も、あまり期待できそうにはない。
まだ対応してないんなら、上記のエラーで当然だと思う。
Foo foo[100] = { Boo(), 0 };
template <class X> void forward_test(X && x) { func(forward<X>(x)); } これをC++03でやろうとしたら template <class X> void forward_test(X & x) {
途中で送っちゃった template <class X> void forward_test(X && x) { func(forward<X>(x)); } これをC++03でやろうとしたら template <class X> void forward_test(X & x) { func(x); } template <class X> void forward_test(X const & x) { func(x); } template <class X> void forward_test(X volatile & x) { func(x); } template <class X> void forward_test(X const volatile & x) { func(x); } 見たいな感じで列挙するしかないの?
完全転送は右辺値参照でしか再現できないぞ
そんなことはない boostにc++03でムーブするライブラリあるし 右辺値参照は単に書きやすさの問題
>>649 ムーブじゃなくて完全転送( perfect forwarding )の話だろう。
そもそも右辺値のないC++03なら
>>647 で最大効率じゃない?
なぜ03で再現したいのか
03で再現したくもない機能なんて0xにもいらないだろ?
>>647 const、volatile修飾で動作を変えないなら後ろの2つは要らないんじゃない?
655 :
654 :2010/09/11(土) 21:06:38
2つじゃなくて3つ
3つ消したらテンポラリを受け取れないね
657 :
654 :2010/09/12(日) 00:32:47
>>656 最初のテンプレートしかなければ
X const &
X volatile &
X const volatile &
全部最初のにマッチするでしょ?
forward_test(Hoge()); がとれないよ どうもforward_test<Hoge>って認識されるっぽい
659 :
654 :2010/09/12(日) 12:17:57
Hoge()はprvalueだから、rvalueへのリファレンスでなければ取れない。 constなlvalueリファレンスでrvalueを束縛できるのが、そもそもおかしいんだよ。
rvalue/lvalueを理解してないやつがunique_ptr使ってコンパイル通らないとか言ってるの見ると笑える
>>661 君がそれで苦労したと言いたいのか?
レベル低すぎ
struct Foo { Bar bar; Baz baz; }; Foo foo; Foo fooo(move(foo)); ってやった場合fooo.barとfooo.bazのコンストラクタは右辺値参照のやつが呼ばれるって決まってるの?
ということは、ちゃんとムーブコンストラクタのなかで各要素をmoveしてやるひつようがあるのね。
当然です
Bar, Bazがmove可能として Foo& operator=(Foo&&) = default; とクラス定義中に書いとけばいいんじゃね?
デフォルトムーブが入ったから
>>663 でいいんじゃないの?
そのdefaultだとメンバ全部moveしてくれるの?
勝手にコード生成しない explicit class Hoge; 構文があればいいのに
>>667-669 根本的なところから理解出来てない
あのね、無理して使わなくていいんだよ、お前らには無理
>>671 くだらないこといってる暇があったら質問に答えるなり解説するなりしたらどうなの?奴隷階級が生意気だよ
>>672 他人に言う前に、自問自答すればいいのに。
酔っぱらいが「酔っぱらいは嫌いだ」って言ってるのと同じだろw
12.8.10 節:
ユーザー定義のコピーコンストラクタがなくて、
かつムーブコンストラクタが暗黙にデリートされなければ、
ムーブコンストラクタが暗黙に定義される。
12.8.17 節:
暗黙のムーブコンストラクタは、メンバーごとにムーブを行う。
これだけ読むと
>>669 は正しい気がする。
すまん。×定義 ○宣言
>暗黙にデリートされなければ暗黙に宣言される 明示的にデリートじゃないの?
>>676 多分↓のことだと思う>暗黙にデリート
12.8.12 節: コピー/ムーブコンストラクタは(中略)の場合、デリートされる。
あと、デフォルトのムーブコンストラクタのみだと、
最終的には
「スカラー型は組み込みの代入演算子で初期化される」 (12.8.17)
に行きつくので、コピーするのと結局変わらない。
extern templateってなんですかー! exportとは違うんですか? explicit instantationとも違うんですか? 全部ex.*で始まってて同じに見えます!!
extern template + explicit instantation = export
exportさんは死んだよ
exportのキーワードは開放されたのかな??
The export keyword is unused but is reserved for future use.
残ってるのね。教えてくれてありがとう。
そういえば range-based for って enum では使いようがないね。 コンパイル時に enum の全要素はわかってるんだから begin/end を適当に決定して内部的によろしくやってくれて range-based for 文を使えるようにしてくれてもいいだろうと思わないでもない。 unroll も簡単にできるだろうし。ただ、型を直接置けないから enum X {...}; とある場合、for (X x: X{}) とでもすればいいのかな。
禿含めC/C++の委員はenum大嫌いだからあまりenumの扱いに期待しない方がいい
enum classは?
enumなかったらフラグが使いにくくて大変じゃない
enumなかったら整数リテラルに名前を付けられないじゃない
K&Rに「あんまり要望がうるっせーから仕方なく適当に入れてやった。クソが」 みたいなことが書いてあったと思う それを受けてD&Eにも「Cのenumがテキトーすぎてクソまみれなので、仕方なくC++で少しクソを拭うことになった。ちくしょう」みたいなことが書いてある あと「どうせお前らが欲しいのはこれだろ→enum BOOL{FALSE,TRUE}。bool使え」とか
望まれてるのはenum classなんかじゃなくて、Pascal系の部分型も作れて集合も扱える列挙型か、 あるいは関数型言語のバリアントかと思うんだけど、どうしてこうなった
enumは不要 static な定数用に class を自分で定義すればいいだけ
それって、case部分に書けないだろ……
range-base for ってそういやVC10に入ってないよな あるとかなり便利になると思うんだが 実装難しいのかな?
コンセプトの仕様が七転八倒してたから入れようが無かったんじゃないのかな? おいらはBOOST_FOREACHをforeachに#defineして使ってる。カウンタ変数にautoも使えて便利でござる。
VC10を開発していた時には、まだコンセプトはドラフトに入ってたんだろう。 というかMSVCはC++コンパイラとして未来がないと思う。 どんなバグ報告をしようと、 「それは些細な問題だから、次のリリースでも直す予定はない」 ときたもんだ。 MSVCはもはや、C++コンパイラ界のIEみたいなもんだぜ。
ひとつのコンパイラ以外ついていけない言語になってしまうと、もはや規格の意味もなくなるけどね……
うっかり実装した結果、0xの仕様変更に合わせて次期バージョンで非互換が出るなんてことは、 商用コンパイラではなかなか難しいからなぁ。
誰がC++0xだといった。C++03すら壊滅的に酷いじゃないか。
c++03との仕様の乖離だったらスレチ
コンセプトが削除された理由がイマイチ分からない どこかで、「コンセプトマップを書くのが面倒くさい」というような記事を読んだことがあるが、 そのあたりの詳細に詳しい人いる? 一般のプログラマも、コンセプトマップを書くことになるのは分かるのだが、 そのことが、コンセプトを規格から外す理由になった経緯が分からん。 だって、一般のプログラマは、そんなに頻繁にコンセプトマップ書くとは思えないから
そもそもコンセプトとはどうあるべきかって所で意見がまとまらなかったから見送られたから 書くのが面倒くさいからどうこうという浅い理由じゃないよ
0xの機能をふんだんに使ったconcept_checkingライブラリで妥協するしかないか とはいうもののconcept_checkingだけでも十分便利だから期待はできそうか
boost concept checkは便利だわ。これを規格化できないかな。
>>693 一応VCは拡張 for each in があるよね?
0x に提案されてるのとちょっと文法違うけど
なにそのC#
gotchaという自覚はあるんだな
03のコードってムーブコンストラクタを書き足さないと場合によってはバグる? 書いてない場合はムーブ禁止みたいなオプションないのかな
全メンバがムーブ可能なら勝手にムーブコンストラクタが作られる、ただしVC2010は(ry 禁止させるならX(X&&) = delete; ただしVC2010は(ry
こっちが何もしなければ、STLがバグってない限り大丈夫だろ。 デフォルトのムーブ動作はコピーすることだし、 コンストラクタ呼び出しが省略される条件もコピーコンストラクタと同じ。
ポインタメンバ変数はデフォルトムーブされるの? デフォルトコピーされるのも考え物だけど
もちろん、ポインター、というかすべてのスカラー型もムーブされる。 ただし、その「ムーブ」とやらは、単に組み込みの代入演算子を呼び出すだけだが。 まあ、メンバーは、普通はポインターじゃなくて、unique_ptrで持つわな。
そんなこといちいち気にしてると禿るぞ Bjarneの頭は必然だったわけか…
ムーブ可能なクラスは、必ずしもコピー可能とは限らない。 (例えばストリームクラスなど) そこで質問ですが、 [コピー可能クラスの集合] ⊂ [ムーブ可能クラスの集合] (つまり、コピー可能ならば、常にムーブ可能か) ですか?それとも [コピー可能クラスの集合] と [ムーブ可能クラスの集合] は無関係 (つまり、コピー可能性とムーブ可能性は無関係か) ですか?
class X{ X(X&&) = delete; X& operator=(const X&) = default X(const X&) = default };
717 :
715 :2010/09/24(金) 22:24:18
>>716 そうですよね。ありがとうございました。
ムーブって理解できない俺がいるんだけど、 自分の設計する全クラスに用意しなくてもいいんだよね? 用意してやることで効率が改善されると考えられる自作クラスにのみ 用意してあげればいいんだよね??
あと値渡しは出来るけどコピーは出来ないクラスもな(mutexとか)
効率なんてRVO/NRVOに任せてムーブOKコピーNGのクラスにだけ用意しとけばいいよ
既存クラスのほとんどはムーブNGコピーNGだろうけどな
んなわけねーだろカス
だってintやポインタのメンバを鬼のように持ってるクラスにとってはムーブもコピーと一緒だろ ムーブも出来るのかもしれないけど禁止だね
pimpl使えカス
ぴんぷる!
ムーブのためにレガシーコードは全部pimplに書き直せって?青いなあ 理想も結構だけど、勝手に古いコード壊すなよ
>>726 テンプレートでラッパー作ればpimpl化なんて即終了ですよね
ひとつひとつ修正するとか笑わせないでくださいよwww
std::type_infoのように、コピーもムーブもする必要のないクラスなら、 別にそれでいいんじゃね? 「既存クラスのほとんど」ってのは疑問だがな。
まあ3割くらいはコピー不要かも
>>723 ポインタを素で置いてるのはバグの元。unique_ptrやshared_ptrやboost::scoped_ptrを使おうぜ。
コピーやムーブの可否が自動的に適用されるよ
コードの芸術性からしたらポインターは生だろー 実用品を作ってる職業プログラマーはスマートポインターを使うべきだと思うけどね。
正直、ポインタ周りで厄介なバグだしたためしがないので いまいちリッチなポインタ使う動機がない
でもshared_ptrではオーバースペックだしunique_ptrじゃ使いにくいってケースのが多いよね実際
C++から外に出ようとするとな
確かに芸術だな 実用コードでは全く使い物にならないという意味で
RAII普通に良く使うけど
ちゃんとRAII適用していいか熟考した上で使うのはいいよ 何も考えずに解放が必要な物にホイホイ使ってるなら危なすぎるから今すぐ止めろ
解放っていうか、開始処理と終了処理がセットになってる物で スコープ内の一時利用で済むような機能はリソース獲得関係なくRAIIにするでしょ。
開放が必要なものに使わない方が怖いだろアホか?
解放処理に失敗する可能性のあるものにはさすがに使わんでしょ
んなこと言ったらなんにも使えねーだろ
だから実用的には何にも使えないんだよ RAIIは「リソース解放は絶対に失敗しない」という仮定に全面的に依存している そして大抵のリアルなリソースはそうではない けど「RAIIは素晴らしいからみんな使おう^^」とか言ってる無責任な本やwebの多くはそんなこと触れてない そのせいで間違った利用が横行している 恐ろしい
開放に失敗したらキューに入れといてプログラム終了時に例外的に処理するんだよカス
リソースに使わんかったらええねん お前ら、beginXXX() 〜 endXXX() とかやるときあるだろ そういうのに使えないか確認してみよう
そのendXXX()は戻り値持たないの?絶対に失敗しないの? 安易にRAIIを使う前に確認してみよう
外部要因に依存してなかったら失敗も糞もあらへん
>>745 ほう、そのプログラムは解放に失敗したファイルやロックを自分が終わるまで握り込むのか
はた迷惑なプログラムだな
間違ったRAIIをあろうことか標準ライブラリがやってるの有様だからなぁ fstreamは万死に値する
>>749 お前の実行環境が分からんが
解放が失敗したリソースはどうすればいいんだ?
もう一度解放を試みるのか?
>>751 失敗の仕方次第だろ
戻り値やerrnoを見てしかるべき処置を執る
もう一度解放が必要かもしれないし、解放不要でそのまま正常系に戻れるかもしれないし、致命傷でプログラムを落とす必要があるかもしれない
実用的プログラムを謳うならそこまでちゃんとしないとね
終了処理が成功したかどうか確認しなくても良い機能ってわりとあるような。 それに失敗したときはassertする時って事わりと多くね。
0x関係無い 釣り乙 0xだとλがあるからscope exit風な処理もマクロで実装出来るね と無理矢理0xに繋げるテスト
匿名テンプレート
RAIIを理解できないやつがRAIIを否定するんだよ
std::set_new_handlerみたいに 失敗時のハンドラを登録できるRAIIを用意すればいんじゃね? 失敗が怖いからRAIIを使わないってのは怖がりすぎな気が hoge_ptr<T> hoge = ...; hoge.set_handler([](){ // リソースの解放失敗時に呼び出される });
アホだから相手にするな
>>757 RAII解放時のエラー処理の話なんだから例外使うとまずい。
デストラクタで例外はC++的にヤバすぎて使えない。
だからハンドラ作って処理させるという逃げの一手にしてるわけで
エラーハンドラとかわざわざ構造を複雑にするだけじゃん デリーターをラップしてその中で処理しろよ
RAIIはりソースの管理が本命だから、デストラクタ内例外はterminateかログして握りつぶす出よいんじゃないか? リソース開放でエラーってヒープ破壊のようなクラッシュ直前のよっぽど異常な状態だろう。
>>762 あー確かにそのとおりだわ。
ハンドラ作るより素直だし良いコードになるね。
うーん何で思いつかなかったんだろ。自分の頭の硬さが嫌になるわ。
デストラクタで例外とか
>>763 ネットワーク越しのファイルとかみたいに
割と日常的にclose(というより正確にはclose時のflush)に失敗しそうなものがあるから困る。
しかも時間をおけば成功しそうだから下手に握りつぶすのも悪手な感じだし。
まぁそんなわけでリソース解放の失敗は別にレアケースではないよと。
みんななんでそんなクリティカルな所にRAII使うんだ
C++でRAII以外にどうやる? で、そのRAII以外の方法はデストラクタに入れられない?
別に普通にデストラクタに書いていいよ デストラクタでやるメリットはスコープ抜けるタイミングを気にしなくていいとこだかんね デストラクタ内でリトライしてもいいし、ログってもいいし、無視してもいいし、アプリをアボンしてもいい デストラクタの中で普段やってるリソース開放処理をやるだけ ただし成功するまでリトライみたいな無限ループと例外だけは使ってはいけない
よくできたRAII用クラスは明示的解放用のメンバがあるだろ。 解放失敗がクリティカルだったり失敗することが多い状況では そのメンバ使った明示的解放と失敗時の処理をすればいい。 そんなことシラネってやつが何も考えずにRAII使っても リソース解放処理が自動で行われる(成否はともかく)という点で 生ポインタや生ハンドル使って解放忘れてリークおこすよりマシって話じゃないの。
それはよくできた設計ではないんだよ、本当は 明示的開放が用意されてるってことはdtorでの自動処理では問題が起こる可能性があるってこと dtorでの開放は危険性がまだ残ったままなのに安全に処理しているような錯覚を生み出す 危険性を認知していないまま安全だと思い込むことはただのうっかりよりも恐ろしい(様々な分野で致命的な事故が起こる原因の多くは間違った安心感からだ) 本来ならばdtorでリソースの生死を判断して生きているならassertするべきなんだよね
assertの意味わかってる? 「表明」だよ
そうだよ 「適切な開放処理を経由している」って条件を表明してるんじゃん
相変わらずここはレベルの低い話してるな
例外って本当に必要なんだろうか
newに失敗したらnullを返す方がいいのか
例外もパワフルすぎて使い方を誤ると酷いことになる機能だな。 入門書とかひたすら「便利でしょ!」みたいな感じだから、みんな勘違いしたままになる。
便利な機能を駆使して 落とし穴を巧妙に一生懸命 作ってるようなもんだよなあ
デストラクタで例外投げれない仕様が全部悪いんだ 何とかならないのか
被せるより生だろ 被せた方が安全かもしれないけど 後処理が出来てれば生の方が 気持ちいいし絶対生。
そして妊娠(リーク)へ……
>>779 例外巻き戻し中に例外を投げたときのエレガントな動作を定義してくれればデストラクタでの例外が可能になるよ。
デストラクタはリソース開放しかしないようにすれば例外投げる必要はなくなるんだよね。
またリソース解放は絶対失敗しないという思い込みか 失敗しないリソース解放なんてfreeとdeleteくらいだというのに
稀に失敗するからこその例外だろ つまりRAIIと例外処理は相補的でC++の設計が理にかなってることを示している
deleteが失敗するのはヒープが破壊されてる常態だから考えなくても良いな
RAIIってなんて発生してるの? ん、俺か? 俺は 雷ッ だな
ラツー
リソース解放は絶対失敗しないという前提でRAII使いまくればいいよ。 現在大きな問題になってる解放忘れによるリークをなくすことが第一。 その後で解放失敗によるリークが無視できない問題になれば ハードウェアやOSの設計レベルでのリソース管理法の見直しも含めて新たな手法が考案されるよ。
わざとポインターのデータを開放しない場合に間違って RAIIを使って開放されてしまう間違いも同等に起きるから どっちもどっちとしか言わざるをえない。
リソース解放に失敗するって、思いつかないのだが、例えば?
>>766 が言ってるclose時のflushはリソース解放じゃないし。
close時の失敗として出てくるんだからそれはclose(リソース解放)の失敗だろ 792はファイル扱う時に常にflushしてからflushしないcloseをしてるの?
close()明示したらflushされるけどRAIIに任せたらflushされずに尻切れトンボになる、 ってのもどうなんだろうな?
そんなの解放のし忘れに比べれば些細なこと RAIIを使わない理由にはならない
>>792 closeの失敗としてバッファの値を何らかの原因で書き出せなかった場合か?
こんなのOSが悪いんでC++の知ったことじゃない。例としてWinが時々出す遅延書き込みの失敗でシステムのイベントとして記録される。
それでもRAIIとしてはファイルハンドルを閉じてしまえば責任を果たしたことになるだろう。
>>793 I/Oエラーでflashに失敗しcloseがエラーを返した場合でもリソースは解放される。
少なくともリークは起こらない。
RAIIを使わないで信頼性/保守性の悪いコード書くよりは最後のデータをwrite
した後に明示的にflushするようにする方がマシだと思う。
>>794 おいらはclose明示すればファイルを残し、closeされずにデストラクトされたらファイルを消すようにしてる。
これなら例外で抜けてもごみは残らない。
RAII + 明示的に処理 はダメなのか? 管理しなきゃいけないものが複数出てきたとき RAIIなしじゃ面倒そう それこそ保守性の悪いコードが出てきそう
>>796 大事なデータの書き損じを、RAIIだと検知できないからって正常系に戻しちゃっといて
「OSが悪い。C++の知ったことじゃない。ファイルハンドル閉じたから責任を果たした」ってか。
おー怖い。絶対に他人様が使うプログラム書くなよ。
>>801 遅延書き込みの失敗を受け取る方法を教えてくれ。
>>802 だから例外や返却値に頼るのでなくハンドラを渡してコールバックしてもらえとあれほど…?…誰も言ってないな
コールバックは処理が癒着するからイヤ
>>802 現在の処理進行度と結果を示してる何かをポーリングで監視。
>>801 は遅延書き込みなんてウルトラ異常系までアプリ側で拾ってるのか・・・
まあ普段はどうでもいいけど、いざ拾わないといけないとなったときに拡張できる余地は欲しいよな。 Windowsとか遅延書き込みに反応するためのAPIまであるし。
>>796 趣味のプロブラムならそれでいい
商用ならクビ
コンパイラに備わってない機能を 無理やり実装しようとするのがそもそもの間違い RAIIを使いたければJavaでもC#つかえばいい。
プログラムを書かないのがプロなんだよ
大体、日本人の癖にアメリカの合理主義に洗脳されて なんでも実利主義でも儲け主義な企業がわるい。 日本人はもともと巧みで繊細な技術だから 無意味なところにもこだわるべき。
プログラミングなんぞに頼らずに すべてを手作業にすべき。
これからの時代はプログラム言語作成言語という言語が出来て、 RAIIをオンにしたり構文の規則をカタマライズしたり 自分好みのプログラミング言語を作る時代に発展していくんだろうな。
>>811 エラーが起きる可能性があることを前提すればよいだけの話
・正常に書き込めたかチェックする(使用した関数の戻り値とかのふざけた方法でなく)
・復旧できる仕組みを用意する
・バックアップを作成する
・データの保存は複数の系統で、重複して行う
趣味のプログラムなら「あららデータなくなっちゃた」で済むけど、
商用では絶対に許されないことだよ
>>817 つまり fstream の仕様はどうするべきだ(だった)と言うの?
現状の仕様でも、趣味のプログラムならデストラクタ任せで、商用で
データロスが許されないなら明示的に close() して戻り値チェックすれば
いいってことで、問題ないんじゃないの?
商用でもデータロストなんてよくあることだろWindows製品とか
Linuxで動くソフトもわりとロストするよね。
Linuxは自己責任だから
822 :
818 :2010/09/27(月) 14:30:59
おっと fstream::close() は void だったか。 exceptions() を設定しとくか、 あとで fail() なり !good() なりでチェックするってことで。
ファイルを書き込んでから 読み込んで書き込んだデータと一致するか調べないと本当に 正常に書き込めたかは分からないよ? それでもやるの?
チェックのための読み込みで失敗するかもしれない
>>821 windowsも自己責任だよ
契約書(だれも読まないけど)にちゃんと書いてある
>>823 printf だってちゃんと出力できたかどうかわからないのに
毎回戻り値ちゃんと見てるのか?
自己責任が嫌なら自分でOSをつくりCPUをつくるしかないだろう。
自分以外誰も信じないで全て疑って掛かるというのが商用だからね
石橋を叩き壊して新しい橋を自分で作るというのが商用なんだろうね。
一番信じられないのは自分だよ
>>823 そういうのが手間だからやらないとでも?
書き込んだはずのデーターが消失するんですよ?
事の重大性がわかってないんじゃない?
うちの会社なら君はクビだ
一生チェック作業やってろ
>>834 馬鹿?
人がやらなくていいようにプログラムがやるんだよ。
メモリに収まりきらないような大量のデータを書き込んだときはどうやって丸ごとチェックするの?
段階的にやればよくね?
>>837 ストリームとじた後に再読込して全体チェックしなきゃいけないんだから段階的にはできないでしょ
複数の系統で保存するって言ってるんだから ハードディスクとハードディスクでチェックすればいいだろ。
0x の話じゃないよね。
板違い
C++で特に0xとか必要としてる分野って 商用アプリ、組み込み系特殊ハード、ゲーム屋くらいかと思ってたけど そうでもないんか 趣味でWindowsでC++ってなんでそんな茨の道?とか思った
>>842 ちょっと前までC++でWINとかふつうだったけど、なにかんがえてるの?
うーんと、金と女かな・・・
残念でした、両方とも得られないでしょう。
>>840 shared_ptrの利用ポリシーにも関わってくるから全く無関係ではない
>>842 > 趣味でWindowsでC++ってなんでそんな茨の道?とか思った
俺は趣味だけど、
コンパイルできてネイティブコードが出力できたり
ライブラリが(外部のね)充実していたりと
最初に取り組んだ言語がCだったりと
いった理由でC++やってる。
でも0xで辟易している。
仕事じゃないからあんまり余暇をC++0xの勉強だけにつぶしたくないし。
辟易したなら別に勉強しなくていいじゃない 0xコンパイラで03コードは(ほぼ)通るんだし perlやpythonみたいに古いコードが壊されないのがC++のいい所
(ほぼ)というにはそれなりの根拠があってのことだろうなぁwwwwwww
↑アホ
そりゃまあ、通らないの確定なところで、新しい予約語がそれまで使ってた識別子に被ったらとかあるしなあ。
あとわかりやすい所だと記憶クラス指定子のautoとexportだな
俺も趣味でC++やってるが、0xはかなり楽しいぞ。 特にラムダとSTLの相性の良さが癖になる。
>>833 どうやってチェックするのかまだわからないんだが。
ファイル読み込みAPIが正常に動作しているという保証がどこにある?
>>853 ほとんどの03コンパイラでexportは通らなかっただろう
>>855 書きこんで読み込めたからといってディスクに書かれているとは限らないしなぁ
833の回答が気になるw
ばーか釣りだよwwwなにマジレスしてんのwwwww
あほにそれ以上構うな
障害耐性スレチもいいとこだろ。本気で知りたいのか?
で、結論は?
素晴らしいものでも馬鹿が使うとだめになる
RAIIが使えるのはメモリかロックくらい ファイルやデータベース接続をRAIIで管理したつもりになってる奴は今すぐやめなさい
煽ってる奴もわけわからんなあ。 APIがぶっ壊れてる(暴走してる?)ケースと、レアでも何でもちゃんとエラーが返ってきて アプリ側で対応できるケースは全然別だろ?
そんなレアなエラーを返すOSが悪い(キリッ
867 :
デフォルトの名無しさん :2010/09/28(火) 01:30:39
例外安全とエラー処理の話を混ぜてどうしたいんだか
エラーを握り潰して「はいno-fail保証です例外安全です」とか勘弁してくれ
それならエラー処理をちゃんとやれ で済むじゃん
エラーを握り潰すのが悪いって分かってるのにRAIIが悪いとか
解放エラーはRAIIじゃちゃんと出来ないと言うとるのに
出来るだろカスが
どうやって? デストラクタ起動した時点でオブジェクトは壊れてるし、例外は当然投げれないんだぞ? staticメンバとかerrnoとかバカなこと言うなよ
具体的なことを何も書かない馬鹿は放ってよし。
でもやり方としては
>>757 で既出な気がする。
そこでリトライ/中途半端な結果で諦める/ファイルを削除する/独自処理(バックアップから書き戻すetc)を
選べればよいのではなかろうか。
コールバックの中から例外投げられないのは辛そうだけど。
そもそも、ユーザーがリソースを解放するという処理は失敗すべきじゃないだろ。哲学的に。 失敗が許されるのは、無効なリソースを開放しようとしたときぐらいなものだ。 解放に失敗しても、やれることは皆無だし。 C++が、あらゆる場所で、デストラクターは失敗しないべきだという前提のもとに設計されているのも、当然だ。 それでも失敗するとしたら、それはリソースの解放以外の何かをやろうとしているせいだ。 同期処理では、すぐに処理が終わらないこと、 例えば、他のスレッドやプロセスとの同期やネットワーク越しなど何らかの環境依存の処理をもって、 失敗としているならば、非同期処理でやるべきだ。 例えば、ユーザーが解放処理をした時点で、スレッドやスレッドプールなどで、そのリソースを、いずれ解放するようにする。 少なくとも、解放処理をした時点で、リソースの解放は、ライブラリ(OSなどのシステムも含む)側が責任を持つべきで、 ユーザー側が責任をもつべきではない。
ユーザー側とライブラリ側の解放処理がごっちゃになっているから混乱するんだよ。 解放処理とは失敗すべきではない。 ユーザー側にとっての解放処理を、 ライブラリ側にとっても「解放」と呼ぶ必要はない。
いや、ディスクの容量が足りなくてetcで書き込めませんでしたー→バックアップから書き戻し、ぐらいは アプリ側でできないと困るだろ…… ライブラリはバックアップのファイル名なんて知る訳ないし
その処理はデストラクターの中ではやれないのかな。
>>879 それがコールバック関数案だと思うんだが、バックアップからの書き戻し(大抵リネームだけだろうけど)すら
失敗する可能性があるんだよなあ。
そうするとどうしても外に例外を投げるなりしてユーザーにダイアログボックスを見せたい。
まあそこまで作り込むなら、デストラクタじゃなくてflushなりcloseを別関数にしろよ、ってのが正しいと思うw
ディスク Full をそこまで気にするなら RAII の哲学的に、先にファイルを確保してから書き込みするべきですね。 先にリソース確保、その後に使う。でしょ? 同様に、必要とされるメモリは事前に確保。少なくともデストラクタ実行時に発生する動的なメモリ確保は、コンストラクタ内で確保しておく。と。
本当にdisk fullを救わないといけないなら closeを保証するブロックの内側にflushを保証する別のブロックをRAIIで作ればいいんじゃないの?
>>881 は正論かもしれんが、
エラーハンドリングしたいときはデストラクタに任せず別関数を呼んでください、のほうが遥かに現実的だな……
大体スタックオーバーフローの可能性もある以上別の関数すら呼べないじゃん……
>>882 flushを保証するブロックで失敗したら、closeを保証するブロックを抜けた上で
(closeしないとファイルを消すこともできないので)
外側でなんかする、ということになると思うんだが、
closeを保証するブロックを抜ける手段として一番便利なのはどう考えても例外なので
flushがRAIIである必要は全くないと思う。普通のメンバ関数で充分。
失敗時にバックアップからの書き戻しとかするような仕様なら テンポラリな名前でファイル書き込んで成功時にリネームするもんじゃね?
>>882 flush を保証するのに RAII 使ったら例外投げれないでしょ。
まとめると、
「 ofstream で書き込み終了したら close() 呼ばないと危ないよ」
で済む話を RAII のせいにしてわめいてるおかしな人が一人、
ってことでおk?
>>885 ああ、普通はその方が正しいな。
どっちにしろ失敗したファイルは消さないといけないけど
ああ、close後にサルベージしたいのか。じゃあflush保証は意味ないな
>>887 >>885 のやり方でいいなら、closeはcloseでリソースリークが起こらないことだけ面倒見て
続行不能なIO例外が飛んできたら一律そこで一時ファイル削除すればいいんじゃないの?
>>889 いいよ。
でもデストラクタは例外飛ばせないので、やっぱりcloseは明示的に呼ぶことになるね。
あとまあ、ファイルのIDを維持したいとかハードリンクを維持したいとかリソースフォークを維持したいとかで
リネームによる解決ができない場合は時々あると思う
>>890 書き込み操作が全部終わった時点で手動でflushして失敗したら例外投げたらいいんじゃないの?
明示的に呼ぶのがcloseかflushのどっちかはこの際問題にされてないと思ったけど?
単にデストラクターの中で例外を使いたいだけなら、 つまり、デストラクターの外に例外を飛ばす必要がないのなら、 デストラクターの中でthreadをつくって、join()すればいいじゃん。
>>892 全然違う
closeは書き込み操作が成功しようが失敗しようが呼ばないといけない
flushはwriteしたいものが全部片付いた時だけ呼べばいい
>>893 えっ
単に外に飛ばさなければいいだけで、デストラクタの中で握りつぶす分には大丈夫と思ってたけど
もしかして違うのか……怖くなってきた
デストラクタ内で例外握りつぶすのがダメだったらほとんど何も出来ないな
>>894 ある程度書き込んだあとflush到達前に例外が飛んだ場合でなおかつdisk fullなら、
デストラクタ経由close経由flushがやっぱり失敗するんでどっちにしろ明示的に……と
書こうとしたが、この場合はもみ消していいのか。すまん。
例外の発生中に、新たな例外を投げることはできない。 デストラクターの中で例外を使うというのは、問題になる。 例外を投げた結果、デストラクターが実行されているとしたらどうなる? struct S { ~S() { try { throw 0 ; } catch(...) { } } } ; void f() { S s ; throw 0 ; // sのデストラクターを呼び出す } この例では、S::~S()の外には例外を投げないものの、 すでに例外が発生しているので、デストラクター内のthrow文を実行した時点で、 例外が重複することになり、エラーとなる。 したがって、例外を投げたことによるデストラクターの実行ではない保証できる場合でしか、 デストラクターの中で、安全に例外を使うことはできない。
899 :
898 :2010/09/28(火) 07:38:51
あ、間違ってた。中で握りつぶす文にはいいのか。
デストラクタの中で発生した例外は握りつぶさないと危険 あとの処理は誰かに任せる
>あとの処理は誰かに任せる どうやって? 何を使えば伝えられるのか?
つか、おまえらの「議論」は極論の塊なのよ。 クリティカルなメモリマネージメントをしたければ、その例外ハンドラ用に「小さな」メモリマネージャを持つ。 とか、もっと簡単にコンストラクタで非常用メモリを確保しておいて、new / alloc でエラーが起きたら、 その非常用メモリを解放して最後の後始末をする。とかね。 ディスクも、システム用に「ちょっと」確保しておいて、最後のログはき出しようにそこを使うとか。 実装レベルではそれで十分だし、それ以上の対策なんて、どちらにしろできないだろ? メモリゼロ、空き容量もゼロであと何ができる?
>>897 flush到達前に例外でたらスコープ抜ける際にcloseされてそのあとキャッチされて後始末
書き込み一通りエラー無しで通ったのにflush失敗した場合でも例外投げたらスコープ以下同文
>>898 デストラクタで例外を投げる可能性がある部分を実行するときは
std::uncaught_exception で例外中かどうか確認してからすべきでは
if( !std::uncaught_exception() ) throw 0; トカ
>>901 デストラクタにしろクローズ処理にしろ、そこまでに処理し忘れていたエラーは全て握り潰すのが基本
エラー拾いたいならそれより前でチェックして例外投げるなり回復処理するなりしなはれ
>>904 http://www.gotw.ca/gotw/047.htm > 2. Consider the following code:
>
> T::~T() {
> if( !std::uncaught_exception() ) {
...
> Is this a good technique? Present arguments for and against.
>
> In short: No, ...
まーだやってんのかお前らも暇だねぇ
{ if(!r.close()) { // エラー処理 } } なんて書くのはアホのする仕事 void Deleter(resource * pr) { if(!r->close()) { // エラー処理(さっきと同じ) } } { resource r(..., Deleter()); } って感じでRAII使って処理するのが仕事で使って良いコード 0xならラムダもあるからコーディングの手間も少ないし、 従来のスタイルと同等の柔軟性もあって、スコープガードとしても機能する リソースの処理をリソース管理クラスの外に丸出しするなんて愚の骨頂でしょ
さっきからエラーを外側で処理しないといけないケースの話をしてるんだが
だからそれが間違ってるんだよ
まだ粘着の相手してんの?お前ら
fj の malloc/free 論争なみにもっとやろうぜ
ここまでのまとめ
発端は
>>737 ,739,742,744。要するに
『解放が必要なリソースを扱うときでも場合によってはRAIIを使わないと言う選択をするべきだ。
なぜならRAIIを使ってリソース解放をデストラクタに一任では解放失敗という事態に対処できないからだ。』
という意見が出る。
で反論。
>>770 ,799とか
『RAII+明示的解放(と解放失敗した場合の処理)、で対処すればいい。RAIIを使うことを否定する意味はない。』
わかってる人にはこの時点で終了。
で、その流れから派生したが本質的でない
・解放処理に失敗したことをどう検知するかという話
・いまだに解放をデストラクタに一任する前提でされている話
・あくまでRAIIを使うべきではないときがあると主張する話
とかをいまだに続けている人がいる。
915 :
デフォルトの名無しさん :2010/09/28(火) 14:54:26
「みながわけんじ」みたいな老害が居るわけね
じゃなくて RAII+明示的解放 は RAII ではない。 ってことでしょ?
RAIIってのは自分の欠は自分で拭くってことなんだよ
言い換えるとウォッシュレットを使わない人ってことですね。
0x関係なくないか?
C++0xにC++は含まれてるから C++のことはC++0xのことでもあるとおもうが。
なんだその理屈
923 :
847 :2010/09/28(火) 17:27:54
>>848 > 0xはやれやれだぜってこと?
そう。
学生時代は落とし穴回避する俺sugeeeeモードでそれなりに
楽しくやれたんだが、そろそろ就職と資格勉強にあたり
あんまり時間も取れなくて、それなのに新しい仕様が
登場してきて勉強しなおしかぁ…って気が沈むんだ。
>>849 > 辟易したなら別に勉強しなくていいじゃない
ところがC++が楽しかった思い出が後ろ髪を引くんだよ。
> perlやpythonみたいに古いコードが壊されないのがC++のいい所
Python 2.x では最近習得し始めて、文字列処理するだけなら
圧倒的にこっちがメイン。
最近 3.x で非互換になっているらしいが先進的な機能は使ってない
(というか使えていない)のでまあ問題無い。
>>854 楽しいのか−。
もう学生気分は終わりだからなー。
長文乙wwwwwwwww
0x の新機能は大体糖衣構文なのだから、別に勉強しなおすって表現する程のものは無いぞ。 分からないものは使う必要は無い。
アセンブリを除けば、すべての言語はシンタックスシュガーであると言える。
高級言語なんてアセンブラのマクロから派生したもんだからな。
assembla でさえ machine language の syntax sugar なんだよな
もとはHEXだしね。 最近のIntelCPUなんかアセンブリ命令がさらにこまかい単位になるんだっけか?w
マイクロopは別に新しい技術じゃないよ。てかスレチ
おまえら極論がすきだな〜。
お前らシンタックスシュガーって言葉が大好きだな
μopとかPenIIの頃からじゃなかったっけか
構文糖衣A錠、医薬品です。
央退散良い薬です
正露丸糖衣Aを「正露丸トウ、イェー」だと思っていた僕の母
お前らもっと建設的な議論をしようぜ。 例えば、 Alternative representations(C++03でいうAlternative token)とか、 asm宣言とか、 vector<bool>とか。
結局そのままなんだよなvector<bool>
そのまま、というのが何を指すのかにも依るけど vector<bool> は deprecated だし、その役目は dynamic_bitset に移譲 されていくことは確かな訳で
なんでvectorあんな仕様にしたんだろうな 標準化委員ってマヌケばっかなのか?
コンテナの要件を満たさないというのがどれだけヒドいことか当時は良く理解してなかった まあ間抜けっちゃ間抜け
std::vector<bool>だけ 過去の物をどうにかして直せないのかな? @過去との互換性を破棄する Astd::vector_container<T>というテンプレートを用意して、 Tがboolで無い限りはstd::vector<T>と同じで Tがboolである場合はコンテナの要件を満たすようにするとか。 (要するにboolでの特殊化をしない) 特に後者Aの方法で解決できないのかな?? そして今後はAを使う様推奨していくってのが良さそうなんだけど。 Aの方式ってデメリットあるのかな? 教えて標準化委員会の人!!
boolの特殊化でvector<bool>のまともな実装と同等のコードを書かないといけない→新しいコンテナ丸ごと作るのと手間がほとんど変わらないのでめんどい
機種依存文字を平気で使える時代になったのはいつから?
vector<char>あたりのラッパー作るだけでいいんじゃないの?
個人的には使う人が便利なら右辺値云々含めて気合いで書き直すべきだと思うけど vectorに関しては既にリリースしちゃったから互換性気にする人がいるんだろうな
当時の委員会を間抜けと言うならそのとき間抜けでない人間はいなかった。 まあこの期に及んでvector<bool>なんて最早全く使わないけどな。 サイズが問題ならbitsetがあるしそうでなければvector<int>で代用すればいい。
vector<bool>がdeprecatedってのは、0xの話じゃなくてユーザーの雰囲気的にってこと? どっちにせよ面倒そうだから使わないようにしてるけど。
結局なんとなくもやもやしながらvector<int>やdeque<bool>を使うしかない
950 :
942 :2010/09/29(水) 14:57:45
>>943 何を言っているのかわからんが、
別にboolを特殊化しないだけであとは既存のvectorのコピペでいいんだから
手間は全くかからないとおもうんだけど。
>>944 丸数字がUnicodeに入った時点で、時代遅れは我々になったのかもしれん
Macで普通に文字化けするっつーの>丸文字 まあソフトとフォント?によるけど
そのソフトがアホなだけだろ。
windows以外はゼンブゴミでOK?
macワロタ なに?人とは違う、おしゃれな私かっこいい、とか思ってんの? 中身のないマイナーOSは引っ込んでろよ
脳味噌の中身がないドザ黙れよ
単にNFCとNFDの差 WindowsもMacも両方対応が不完全
つうか機種依存とか気にしてたらAA書けないし 実際機種の問題じゃなくて掲示板見るときの設定がオカシイってだけでしょ
>>957 丸付き数字なら、cp932とsjis-macで割り当ててるコードポイントが違うのが原因じゃねーかと思う。
@
勝手に引数を暗黙変換しない void f(explicit bool); という構文があればいいのに
お前センスあるな
>>962 なんかそれっぽいの無かったっけ?
自分でMyBoolってクラスを作って、
explicitコンストラクタで bool型だけを受け付けて、
void f(MyBool myb);内に入るとすぐMyBoolが格納しているbool値を放出して
受け取ってもらうってのはらめなの?
汚すぎる
>>965 ってことは一応可能って事?
自分で描いててこれじゃあんまり有用性無い気がしてきた。
大体
void f(true);
が通らないよねこれだと
void f(bool){ ... } void f(...){ static_assert(false, "ダメよ♪"); }
>>967 それって通るコード?
0xって良くわかんない。
テンプレートじゃないとダメか。 void f(bool){ ... } template <class T> void f(T const&){ static_assert(false, "らめぇー"); }
>>969 その場合、コンパイル時にトラップするだけのための関数を
エラーになるように定義するのも面倒なので
template <class T>
void f(T) = static_assert;
とでも書くと、コンパイラがエラーメッセージを出すようになっていればいいのに
メタプロ用の仕様もっとモリモリ拡張すればよかったのにね これが実体化したらこれこれこうする〜とか
Defaulted and Deleted Functionsがテンプレートでも使えるような気がしないか?
Defaultedはクラス以外で使い道ない。 Deletedにすると、boolの例だと逆にトラップ先が無くなって 何でもかんでもboolに集まってくることになる
暗黙の型変換はint←→longみたいなのも含めて全部なしにして、 C言語と互換性のある型変換は#include<implicit>みたいなのにすればいいのかな。
>>974 > C言語と互換性のある型変換は#include<implicit>みたいなのにすればいいのかな。
何を言っているんだ
#includeって何をしていると思っているんだ
#includeじゃなかったとしてもプリプロセッサレベルでどうやって解決しろと。
>>973 >Deletedにすると、boolの例だと逆にトラップ先が無くなって
>何でもかんでもboolに集まってくることになる
試してみたら、bool以外を弾いてくれてたよ。
hoge.cc: In function ‘int main(int, char**)’:
hoge.cc:3:26: error: deleted function ‘void f(T) [with T = int]’
hoge.cc:6:6: error: used here
hoge.cc
--
void f(bool){}
template<typename T>void f(T) = delete;
int main(int,char**){
f(1);
return 0;
}
>>975 中にはoperator int(long);みたいなのがたくさん入ってるのを考えてた。
978 :
972 :2010/09/30(木) 21:56:47
てか One can define a template with a deleted definition. Specialization and argument deduction occur as they would with a regular template function. って書いてあるな
= default; はスペシャルファンクションだけって書いてあるけど、
= delete; はそういう制限ないんだね。
それに、
8.4.3.2 のノートを見る限り
>>976 が正しいみたい。
とりあえず暗黙の型変換対策は deleted関数でOKってことのようで
>>980 そうっぽいけど
誰か仕様書に基づき解説してくれ
教えて頭いい人!
そろそろ次スレだけど この4ヶ月でなんか大きな動きあったっけ?
俺がVC++を見限ったことぐらいかな
VC++2010のパッケージ版が出たことぐらいかな
gccが、nullptr、range-based for、noexceptの一部、をサポートしたことぐらいか。
>>981 n3126 の中を delete で検索すると、「〜できる」みたいな積極的な記述はないけど
言葉のはしばしから窺えることがある(★)。
8.4.3.2
デリートした関数を(暗黙にも明示的にも)参照するプログラムはエラー。
(中略)
関数がオーバーロードされてるときは、オーバーロード解決で選択されたときのみ参照される
★= delete; でオーバーロードできる。
★オーバーロード解決でデリートした関数が選ばれたときにエラー。
14.7.3
以下のものは、頭に template<> を付けて明示的に特殊化できる:
・(削除→デリートされてない←削除)メンバ・非メンバ関数テンプレート
・(後略)
★関数テンプレートも =delete; できる。
★=delete; した関数テンプレートも、明示的特殊化で使えるようにできる。
14.7.12
関数テンプレートを明示的に特殊化するときは、
そのときに inline を付けるか、もしくはデリートしたときのみインラインになる。
元のジェネリックなやつがインラインかどうかは関係ない。
★明示的特殊化で =delete; 可能。
987 :
986 :2010/09/30(木) 23:49:54
あれ? 俺間違ってる? explicit specializationは「宣言」だから、関数定義はできないのか。 じゃあ × =delete; した関数テンプレートも、明示的特殊化で使えるようにできる。 × 明示的特殊化で =delete; 可能。 はウソだ。
というか何でお前ら、「関数のdeleted定義はメンバー関数に限る」みたいな誤解をしているんだ? そんなこと、規格のどこにも書いていないじゃないか。 まあ、サンプルコードはメンバー関数の場合しか載っていないというのはあるがな。
>>988 「deletedな関数は呼び出すべき関数の探索対象にならない」という誤解をしている人はいたが、
「メンバ関数に限る」という誤解をしている人はいないように見える。
>>987 >じゃあ
>× =delete; した関数テンプレートも、明示的特殊化で使えるようにできる。
>× 明示的特殊化で =delete; 可能。
>はウソだ。
こういう話?
仕様は読んでないが、とりあえずgcc-4.5.1ではコンパイルを通った。
--
// deleteした関数テンプレートを明示的特殊化で使えるように
template<int>void f()=delete;
template<>void f<1>(){}
// 明示的特殊化でdelete
template<int>void g(){}
template<>void g<1>()=delete;
int main(int,char**){
f<1>();
g<0>();
return 0;
}
なんか皆がどのへんの理解に苦しんでいるのかがわからない。 関数のdeleted定義は、その名前のとおり、関数の定義である。 deleted定義によって定義された名前は、宣言以外の目的で使うことはできない。 使った場合はエラーとなる。 もちろん、関数呼び出しはできないし、未評価式の中でも使えない。 void f() = delete ; void f() ; // OK、再宣言 int main() { f() ; // エラー、関数呼び出し typedef decltype(f) * type = &f ; // エラー、decltypeの未評価式と、&演算子のオペランド } それ以外は、通常の関数の定義とまったく同じように振舞う。 もちろん、name lookupで見つかるし、テンプレートならばインスタンス化されるし、オーバーロード解決の際にも考慮される。 ただし、そうした結果として選ばれた名前が、deleted定義であった場合、その名前を使うとエラーとなる。
>>992 > なんか皆がどのへんの理解に苦しんでいるのかがわからない。
というかC++0xのカオス状態の規格を読んでも
いまいちぴんと来ないのだ。
単に俺がバカなだけかもしれんけど。
>>992 decltypeやsizeof中での使用を禁止してるのは何か深い理由があってのことですか?
>>994 さあ?
しかし、
void f() = delete ;
に対して、
f() ;
がエラーとなるのに、
typedef decltype( f() ) type ;
がエラーとならない、というのは、違和感がある。
>>990 ,991
template <class T> void f(T){}
template <> void f<>(int){} //A
void f(int){} //B
A,Bの違いが判らなくなって血迷った。
f(1) は B、f<int>(1) は A だとか、そんなことだったっけ。
.
.
∧,,,∧ ( ・∀・) 1000ならジュースでも飲むか ( ) し─J
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。