トップページ⇒tech
1001コメント261KB

C++0x 11

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2010/10/01(金) 07:04:54
The C++ Standards Committee
http://www.open-std.org/jtc1/sc22/wg21/

Wikipedia
http://ja.wikipedia.org/wiki/C%2B%2B0x

前スレ: C++0x 10
http://hibari.2ch.net/test/read.cgi/tech/1275375522/
0232デフォルトの名無しさん2010/10/25(月) 13:32:01
beginとendと*itを書く事すらめんどくさいから
0233デフォルトの名無しさん2010/10/25(月) 13:32:37
あとはアダプタ噛ませるときに便利だから
0234デフォルトの名無しさん2010/10/25(月) 19:10:38
>>230
例えばxvalue, lvalue, prvalueには具体的にそれぞれどんなものが該当するの?
0235デフォルトの名無しさん2010/10/25(月) 20:11:01
>>231
配列だと .begin() とか書けないから
0236デフォルトの名無しさん2010/10/25(月) 21:10:36
さすがに右辺値と左辺値の区別くらいはついてないと、コンパイルエラーも読めないんじゃないか?
0237デフォルトの名無しさん2010/10/25(月) 21:16:54
lvalueは今まで通りのlvalue
prvalueは今まで通りのrvalue
xvalueは右辺値参照のこと

使う時はこれくらいの理解でおk
0238デフォルトの名無しさん2010/10/25(月) 21:36:13
lやrまではまだいいとして、pとかxとかわかんねえだろ
分かりやすくするという気はないのかね?
0239デフォルトの名無しさん2010/10/25(月) 21:43:57
お前がわかりやすい名称を提案すればいいんじゃないかな?
0240デフォルトの名無しさん2010/10/25(月) 21:57:11
省略するからだめなんだよ
0241デフォルトの名無しさん2010/10/25(月) 22:02:00
prvalueって見た目通りpointer rvalueなんすか?
0242デフォルトの名無しさん2010/10/25(月) 22:02:34
pureだろう
0243デフォルトの名無しさん2010/10/25(月) 23:34:26
「ムーブ可能」ってどういうこと?定義あるの?

処理前のオブジェクトの束縛が、処理後に無くなっても問題ないってことでおk?
0244デフォルトの名無しさん2010/10/25(月) 23:39:32
>>238
名前がどうのこうの言う前に概念理解してないだろ。
素直になれ。名前なんて単なる名前だ。酷い命名でもないし。
0245デフォルトの名無しさん2010/10/26(火) 00:02:22
>>243
もう必要ないから中身を好きなようにぶち壊してよい物体のこと
0246デフォルトの名無しさん2010/10/26(火) 00:03:24
>>244の書いたコードが見てみたいな
0247デフォルトの名無しさん2010/10/26(火) 05:42:21
>>234
lvalueはC++03から何も変わらない。
名前のついている変数やポインターのdereferenceやリファレンスなど。
rvalueリファレンスの変数も、もちろんlvalueとなる。
lvalueは、安全にムーブできない(ユーザーがどのように使うか分からないため)

prvalue(pure rvalue)は、主に一時オブジェクト。
名前がなく、ストレージが確保されている保証もない値。
リファレンス型以外の関数の戻り値とかがこれに該当する。
prvalueは、安全にムーブできる(ユーザーは自由に利用できないため)

xvalue(eXpiring value)は、ユーザーが意図的に作り出すもの。
つまり、lvalueやprvalueを、ユーザーが意図的にxvalueにキャストして、ムーブ可能であることを示す。
static_cast<T &&>(t)や、関数の戻り値の型がrvalueリファレンスの場合、xvalueとなる。

ほかにも、return文でローカル変数をオペランドに渡したときとか、暗黙にムーブが発生することとかがある。

>>244
内部で動的に確保した、何らかのリソースをぶんどってもよいかどうか。
コピー先のオブジェクトが、コピー元を使えない状態にしてもいいかどうか。
std::auto_ptrのようなもの。auto_ptrの場合、コピー後、コピー元は妥当なポインターを持たなくなる。
rvalueリファレンスができたおかげで、auto_ptrはめでたくdeprecatedになったけど。
0248デフォルトの名無しさん2010/10/26(火) 06:41:16
>>231
autoって大昔のcのころの機能イメージがあってちょっとコードみててもにょるのが難点
0249デフォルトの名無しさん2010/10/26(火) 11:14:46
>>247

>prvalue(pure rvalue)は、主に一時オブジェクト。
>名前がなく、ストレージが確保されている保証もない値。
>リファレンス型以外の関数の戻り値とかがこれに該当する。
>prvalueは、安全にムーブできる(ユーザーは自由に利用できないため)

こめん、上の2行目と4行目の記述が矛盾しているように見える。
「ストレージが確保されている保証もない値」 なら 「安全にムーブ」 でき
ないと思うけど。

「ストレージが確保されている保証もない」 が 「メモリが、名前のある
ポインタ変数によって管理されていない」 という意味ならわからんでも
ないが。


「Move(移動)」とは、右辺値オブジェクト(一時オブジェクト)が(そのデータ
メンバであるポインタを通して)管理している動的メモリを、左辺値オブジ
ェクトが管理している動的メモリとswapすることだと勝手に解釈してたけど、
これって間違い?

両者の動的メモリのアドレスをswapすれば、メモリのコピーも必要ないし、
右辺値オブジェクトはどうせ破壊されるから問題ないと思ってたけど。
0250デフォルトの名無しさん2010/10/26(火) 11:26:20
int x = 0 ; int y = 0 ;
int z = x + y ;

ここで、x + yという式を評価した場合、その結果を表す一時オブジェクトが生成されるが、
この一時オブジェクトは、具体的なストレージを持たなくてもよい。

ただし、xvalueにされたときは、具体的なストレージが必要となる。

int && rref = x + y ;

ムーブは、言語的にいえば、ムーブコンストラクターかムーブ代入演算子を呼び出すこと。
ライブラリ的にいえば、仮引数の型がrvalueリファレンスな関数も、ムーブしていると言える。

ムーブの具体的な実装は、好きにすればいい。
体一、コピーの具体的な実装も、好きにしていいのだから。
もちろん、デフォルトのコピー、ムーブコンストラクターや代入演算子の定義はあるけどね。
0251デフォルトの名無しさん2010/10/26(火) 16:40:54
ストレージってメモリ上ってこと?
それなら、その保証がないのはlvalueだってアドレス参照されない限り
同じなのでは?
0252デフォルトの名無しさん2010/10/26(火) 18:20:59
「常に可能であること」を「保証されている」と日本語では言う。
e.g. 常にアドレス参照可能

0253デフォルトの名無しさん2010/10/26(火) 20:32:07
VC++2010なんだけど、ムーブ後なのにf1()もf2()も普通に呼べちゃうのはなんで?

#include <functional>

int main()
{
std::function<void()> f1 = [&]() { std::cout << "1" << std::endl; };
std::function<void()> f2 = std::move(f1);
f1();
f2();

return 0;
}
0254デフォルトの名無しさん2010/10/26(火) 20:51:18
ムーブコンストラクタが無いから参照になってるんじゃ
0255デフォルトの名無しさん2010/10/26(火) 20:52:40
ムーブ後の変数は使える保証はなくなるけど、必ずしも使えなくなる
わけじゃないよね。
0256デフォルトの名無しさん2010/10/26(火) 20:53:22
deleteされた領域を参照すると値が残ってたりするのと一緒
0257デフォルトの名無しさん2010/10/26(火) 21:04:53
あくまでも高速化のための機能だから、nullで埋めるなんてことはしてくれないんだね。
0258デフォルトの名無しさん2010/10/26(火) 22:50:42
[&]() { std::cout << "1" << std::endl; };

これやっぱ何回見ても気持ち悪いわ
C++0xで最も汚いのはラムダ式だと思う
0259デフォルトの名無しさん2010/10/26(火) 23:01:48
代替案を出さなかったのが悪い
0260デフォルトの名無しさん2010/10/26(火) 23:13:36
ラムダさんは使いつづけてると
やっぱりこの形しかないかなぁと思えてくるよ
0261デフォルトの名無しさん2010/10/26(火) 23:21:52
int x;
lambda(int a) { vcap.x = a; } //値キャプチャ
lambda(int a) { rcap.x = a; } // 参照キャプチャ
0262デフォルトの名無しさん2010/10/26(火) 23:37:31
C++0x版のD&Eが今から楽しみだな
ビャーネ・ストロヴストルップ先生のブツクサ文句が山ほど書かれていると思うと・・・
0263デフォルトの名無しさん2010/10/26(火) 23:46:16
弾道軌道からの眺めも書いてくれるかな
0264デフォルトの名無しさん2010/10/26(火) 23:47:03
俺はEC++0xが楽しみ
0265デフォルトの名無しさん2010/10/26(火) 23:52:46
>>253
VC++2010もってないしstd::moveも引数に何とるのか解らんけど、
std::moveがMove Constractorと同じ意味合のものだとしたらマズくね?
なんで名前が使えるものを渡されてコンパイルエラーにならないんだ?
0266デフォルトの名無しさん2010/10/26(火) 23:58:21
>>265
std::moveでキャストしてるからコンパイルエラーにならない
0267デフォルトの名無しさん2010/10/27(水) 00:02:05
std::move() ってのが一種のキャストというか、無理を押し通すための道具だから。
0268デフォルトの名無しさん2010/10/27(水) 00:03:16
>>258
もうすっかり慣れっこになったけど、時々C#のラムダ式を書くとき混乱する。
0269デフォルトの名無しさん2010/10/27(水) 00:58:59
>>267
んなもん何のために使うのかさっぱりわからんなぁ。
const_castを全く使わんからかもしれんけど。
(旧C互換で定数をchar*で渡す関数にしか使ったこと無い)
0270デフォルトの名無しさん2010/10/27(水) 01:06:26
左辺値を強制的に右辺値に変更する働きをする
これで意味が分からなかったらぐぐれ
0271デフォルトの名無しさん2010/10/27(水) 01:12:37
コピーコンストラクタとムーブコンストラクタに限らず、左辺値参照と右辺値参照を取る
オーバーロードがあって、しかも効率の差が大きい場合、

void hoge(int &x); // 左辺値を渡しても安全だけど遅い
void hoge(int &&x); // 左辺値を渡すと安全は保証されないけど速い

左辺値をどうしても下の関数に渡したい時に使う。
0272デフォルトの名無しさん2010/10/27(水) 01:14:49
>>255-256
つまり、VC++2010のムーブの実装はswapじゃないってこと?
0273デフォルトの名無しさん2010/10/27(水) 01:20:10
>>272
つうか、おそらく単なる参照渡し。
ムーブ後の抜け殻に触った結果はどうせ未定義なんだから、仕様は満たしてるよね。
0274デフォルトの名無しさん2010/10/27(水) 01:34:14
こんなんなってた

11: std::function<void()> f1 = [&]() { std::cout << "1" << std::endl; };
00411750 xor eax,eax
00411752 mov byte ptr [ebp-121h],al
00411758 movzx ecx,byte ptr [ebp-121h]
0041175F push ecx
00411760 lea ecx,[ebp-2Ch]
00411763 call std::tr1::function<void __cdecl(void)>::function<void __cdecl(void)><`anonymous namespace'::<lambda0> > (41104Bh)
00411768 mov dword ptr [ebp-4],0
12: std::function<void()> f2 = std::move(f1);
0041176F lea eax,[ebp-2Ch]
00411772 push eax
00411773 call std::move<std::tr1::function<void __cdecl(void)> &> (41110Eh)
00411778 add esp,4
0041177B push eax
0041177C lea ecx,[ebp-4Ch]
0041177F call std::tr1::function<void __cdecl(void)>::function<void __cdecl(void)> (411096h)
00411784 mov byte ptr [ebp-4],1
13: f1();
00411788 lea ecx,[ebp-2Ch]
0041178B call std::tr1::_Function_impl0<void>::operator() (41126Ch)
14: f2();
00411790 lea ecx,[ebp-4Ch]
00411793 call std::tr1::_Function_impl0<void>::operator() (41126Ch)
0275デフォルトの名無しさん2010/10/27(水) 01:35:31
>>272
中身がただの関数ポインタになってて、ポインタのムーブはただのコピーが最善手
ってことじゃないかな?
0276デフォルトの名無しさん2010/10/27(水) 06:41:36
というか、std::moveは、単にrvalueリファレンスにキャストするだけだ。
std::move(t)と書くのは、static_cast<T &&>(t)と書くのと同じだ。
別にムーブと同等の処理は、非constなlvalueリファレンスを引数に取る関数でもできる。
単に所有権の移動と考えろ。

クラスのオブジェクト自体が魔法のようになくなったりはしない。
0277デフォルトの名無しさん2010/10/27(水) 09:17:19
右辺値参照を受け取る側は元の値を「気兼ねなく破壊できる」ってだけで
破壊する義務はないってことか。
0278デフォルトの名無しさん2010/10/27(水) 09:44:10
rvalueリファレンスは、あくまでただの「リファレンス」だからな。
rvalues(xvalueとprvalue)で初期化しなければならないこと以外は、lvalueリファレンスと何ら変わらない。
もちろん、rvalueリファレンスの変数自体を評価するとlvalueだ。

int && ref = 0 ;// OK、0はprvalue
int && aho = rref ; // エラー、rrefはlvalue
0279デフォルトの名無しさん2010/10/27(水) 18:10:59
>>278
rvalueリファレンスの変数を評価したらxvalueじゃないの?
0280デフォルトの名無しさん2010/10/27(水) 18:14:08
Non
0281デフォルトの名無しさん2010/10/27(水) 19:01:24
>>253
そのラムダ式の()は不要だよね。
ネットで見かけるコードだと、相当な上級者の書いたコードでも()が
ついてるけど、なんでみんな書きたがるのか。
でもさすがに某標準化委員は書いてなかった。
0282デフォルトの名無しさん2010/10/27(水) 19:03:24
規格を読まず他人のコードを読むから
0283デフォルトの名無しさん2010/10/27(水) 19:06:16
別に書いちゃいかんというルールもないし。
0284デフォルトの名無しさん2010/10/27(水) 19:25:30
省略するのはなんか気持ち悪いじゃん
慣れの問題だろうけど
0285デフォルトの名無しさん2010/10/27(水) 19:46:57
引数有る無しで書き方を変えるのが変わるのが嫌、とか
0286デフォルトの名無しさん2010/10/27(水) 19:48:43
ラムダの時に()を省略できるなら、普通の関数宣言でも()を省略できてもいいじゃない
0287デフォルトの名無しさん2010/10/27(水) 20:33:52
こうなのか?
std::function<void()> f1 = [&]{ std::cout << "1" << std::endl; };

やっぱり括弧つけようよ
0288デフォルトの名無しさん2010/10/27(水) 20:48:04
#include <iostream>
いやいやこれで十分でしょう。

int main()
{
[]{ std::cout << "1" << std::endl; }();
return 0;
}

なるほど、ファンクタクラスを作るシンタックスシュガーなんだなあ。
02892882010/10/27(水) 20:49:04
しまった。行が入れ替わったw
0290デフォルトの名無しさん2010/10/27(水) 21:05:45
#include <iostream>
//いやいやこれで十分でしょう。

int main()
{
[]{ std::cout << "1" << std::endl; }();
return 0;
}
0291デフォルトの名無しさん2010/10/27(水) 21:11:48
#include <iostream>
//つまりこれと等価ということか

struct x {
void operator()() { std::cout << "1" << std::endl; }
};

int main() {
x()();
return 0;
}
0292デフォルトの名無しさん2010/10/27(水) 21:23:59
Delphi/C#のpropertyみたいなものは導入されないんですか?
0293デフォルトの名無しさん2010/10/27(水) 21:27:34
知らずに0x使うと爆死するようなトラップ要素って右辺値参照さんのほかになんか有りますか?
0294デフォルトの名無しさん2010/10/27(水) 21:33:20
>>292
Javaには入る。
C++はもっとprimitiveな機構に分解できれば入ると思う。
0295デフォルトの名無しさん2010/10/27(水) 21:39:49
>>292
n1615みたいなのは(作れば)あるけど規格には入らないだろうね
0296デフォルトの名無しさん2010/10/27(水) 21:53:39
>>291
// #1-n と #2-n は等価。
int main()
{
 using namespace std;
 { // #1
  int i = 0;
  auto x1 = [] { cout << "#1-1. " << endl; };
  auto x2 = [i] { cout << "#1-2. " << i << endl; };
  auto x3 = [i]() mutable { cout << "#1-3. " << ++i << endl; };
  auto x4 = [&i] { cout << "#1-4. " << ++i << endl; };
  x1(); x2(); x3(); x4();
}
 { // #2
  int i = 0;
  struct { void operator()() const { cout << "#2-1. " << endl; } } const x1 = {};
  struct { int const i; void operator()() const { cout << "#2-2. " << i << endl; } } const x2 = {i};
  struct { int mutable i; void operator()() const { cout << "#2-3. " << ++i << endl; } } const x3 = {i};
  struct { int & i; void operator()() { cout << "#2-3. " << ++i << endl; } } x4 = {i};
  x1(); x2(); x3(); x4();
}
}
0297デフォルトの名無しさん2010/10/27(水) 21:54:01
そう言えばVCに__declspec(property)ってあったよな。
0298デフォルトの名無しさん2010/10/28(木) 15:55:58
ラムダ関数を変数に格納する場合、インスタンスと参照、どちらを格納したことになるんでしょう?

1: auto func=[](int x,int y){return x+y;};
2: {
3:   func=[](int x,int y){return x-y;};
4: }
5: std::cout<<func(2,1);   //出力:1

3行目にfuncにラムダ関数を代入していますが、
これが参照なら5行目はスコープ外ですから動作が不定になりそうです
g++4.5.1では1が出力されたのですが
0299デフォルトの名無しさん2010/10/28(木) 16:02:10
インスタンスという認識でいいと思うよ
0300デフォルトの名無しさん2010/10/28(木) 16:04:58
参照でもinfinite extentなら問題ない。
どうせimmutableなんだから。
0301デフォルトの名無しさん2010/10/28(木) 16:10:42
ありがとうございます
std::function,queueと組み合わせてタスクキュー的なものを作りたくて

関数が変数みたいに使えるって便利ですね
0302デフォルトの名無しさん2010/10/28(木) 16:17:32
>>298
何もキャプチャーしてないが、typoか?
0303デフォルトの名無しさん2010/10/28(木) 17:33:02
>>302
何かをキャプチャしなければならないというルールはないよ
0304デフォルトの名無しさん2010/10/28(木) 18:03:58
typoを修正してくれるライブラリ。Boost.Typoみたいな感じで誰か作ってくれないかな
0305デフォルトの名無しさん2010/10/28(木) 18:41:57
なにもかもがBoost.Typoの意図通りに捻じ曲げられそう…
0306デフォルトの名無しさん2010/10/28(木) 21:23:21
main
{
0307デフォルトの名無しさん2010/10/28(木) 21:24:14
あとはboost::typoにお任せるぜ
0308デフォルトの名無しさん2010/10/29(金) 01:05:17
>>293
右辺値参照がどうやって「爆死するようなトラップ要素」になるの?
0309デフォルトの名無しさん2010/10/29(金) 01:14:33
class Hoge
{
int * p;
public:
Hoge(int n) : p(new int(n)) {}
Hoge(Hoge const & o) : mp(new int(*o.p)) {}
~Hoge(void) { delete p; }
};
こういうクラスで暗黙にmoveされたらテンポラリとmove先両方でdeleteされてまずくない?
0310デフォルトの名無しさん2010/10/29(金) 01:17:45
>>309
そんなわけで暗黙のムーブコンストラクタは無しになったのさ。 >>126 参照。

ちなみにそのクラス定義だと現行の C++ でも代入で死ぬよ。
0311デフォルトの名無しさん2010/10/29(金) 08:39:40
まだなくなると決まったわけじゃない。
特に、禿がひいきにしているからな。
禿によると、そもそも暗黙のコピーも、ユーザー定義デストラクターがあった場合、
暗黙に生成されないべきなんだとさ。
0312デフォルトの名無しさん2010/10/29(金) 09:43:48
まあ=defaultで明示的にってのは悪くない考えだけど、いまさらなあ…
0313デフォルトの名無しさん2010/10/29(金) 12:23:29
しかし今までのコードと互換性が無くなったらストレスで俺たちがハゲになっちまう
0314デフォルトの名無しさん2010/10/29(金) 12:46:22
もういっそC++++作れよ
0315デフォルトの名無しさん2010/10/29(金) 12:46:55
本物の C++ 使いはハゲを恐れない。
0316デフォルトの名無しさん2010/10/29(金) 17:22:33
というかもう殆ど禿げてる
まだ20なかばなのに
0317デフォルトの名無しさん2010/10/29(金) 17:42:17
>>316
いつ新しい言語を設計するんですか?
C++と同等に使えて、evalも用意されている言語をお願いします。
0318デフォルトの名無しさん2010/10/29(金) 18:37:26
>>317
evalはちょっと欠陥品だろう。
頼むからもうちょっとまともな仕様の言語が欲しい。
0319デフォルトの名無しさん2010/10/29(金) 18:56:45
まあC++1xでconcept入ってしばらくしたら、
その辺の成果を全部生かした言語も作られるんじゃないでしょうか。
0320デフォルトの名無しさん2010/10/29(金) 19:27:58
いい加減新しい言語作って若いもんに覚えさせたほうが人類のためになるよね
人類はいつまでC系列にしがみつく気なんだろう
0321デフォルトの名無しさん2010/10/29(金) 19:32:42
プリプロセッサまわりが汚すぎて、既存のライブラリを確実に移植する方法が
手作業以外に無いんだから仕方ない。
OSのAPIから新言語で提供されていれば話は違うんだろうけど、それも既にModulaが通った道だ。
0322デフォルトの名無しさん2010/10/29(金) 20:24:03
>>320
だからお前がまず代替案を出せよ

C++0xのラムダ式も誰も代替案を出さないからあの汚い形のままなんだぞ
0323デフォルトの名無しさん2010/10/29(金) 20:26:09
functionとかキーワード化したいよなぁ。
というか、将来のために基本的な英単語を予約しておかなかったのが、そもそもの間違いだった。
0324デフォルトの名無しさん2010/10/29(金) 20:27:49
functionって毎回書くの長ったらしくないか?
0325デフォルトの名無しさん2010/10/29(金) 20:31:17
>>320
事情はx86CPUと似ていると思うよ
アーキテクチャがいかに汚くなろうと、過去の財産を大事にすると生き残る
0326デフォルトの名無しさん2010/10/29(金) 21:00:41
互換性を窓から投げ捨てろ
つうか生き残らなくていいからどんどん新しい物を作って破って捨てろ
0327デフォルトの名無しさん2010/10/29(金) 21:12:09
お前がこのスレに要らん
0328デフォルトの名無しさん2010/10/29(金) 21:22:46
>>309
デフォルトコピーコンストラクターが使えないクラスにデフォルトムーブコピーコンストラクタを望むのが間違ってるよ。
デフォルトコピーコンストラクタが可能なクラスなら、おそらくデフォルトムーブコンストラクタが可能じゃないか?こいつらはセットだよ
コピーコンストラクタもムーブコンストラクタも定義されていないクラスのみデフォルトコピーコンストラクタとデフォルトムーブコンストラクタを許可すればすむと思うが、どうか?
0329デフォルトの名無しさん2010/10/29(金) 21:25:30
>>324
typedef function<int(int,int,int)> func_type;してから使うから気にしない。
0330デフォルトの名無しさん2010/10/29(金) 21:26:36
>>326
互換性を捨てるならC++である必要はなく、DでもEでもFでも作ればいいんじゃね?
0331デフォルトの名無しさん2010/10/29(金) 22:00:22
最近の新言語ってJavaもどきとLLと関数型ばっかりでつまらん
結局代わりになる言語を誰も作ろうとしないのよね
■ このスレッドは過去ログ倉庫に格納されています