問題タブ [rvalue-reference]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - GCC の右辺値で多くのコピーを生成する標準ライブラリ コンテナー
Linux と Windows の両方でアプリを作成していますが、GCC ビルドがコピー コンストラクターへの無駄な呼び出しを大量に生成していることに気付きました。
この動作を生成するコードの例を次に示します。
このテストは、3 つの要素のベクトルを作成するだけです。左辺値がないため、3 つのデフォルト コンストラクター呼び出しと 0 コピーが必要A
です。
Visual C++ 2010 では、出力は次のようになります。
GCC 4.4.0 (MinGW) (-O2 -std=c++0x) では、出力は次のようになります。
何が起こっていて、どうすれば修正できますか? コピーは実際のクラスに対して高価であり、デフォルトの構築と移動は安価です。
c++ - std::bindを介して右辺値を渡す
std::bind
C++0xで右辺値参照を受け取る関数に右辺値を渡したい。どうしたらいいのかわからない。例えば:
c++ - const への右辺値参照は役に立ちますか?
ないと思いますが、確認したいと思います。の用途はありますか? クラス型はconst Foo&&
どこにありますか?Foo
c++ - C++ - Behavior of function template specialization with rvalue reference
I'm trying to implement a conditional pointer dereferencing function. The basic idea is as follows:
#xA;In order to limit the number of necessary specialization, I'm attempting to use rvalue references for the case where arg
is not a pointer. Here is my current implementation (the std::cout
are there solely for debugging purpose):
Now, I get a rather strange behavior under GCC 4.6. The first overload is used for both the non-pointer types and the pointer types. Obviously, when using a pointer type, it conflicts with the second overload. If I comment out the second one and call the following using the first one...
#xA;... the corresponding console output is:
#xA;How is it possible that a non-pointer type (according to std::is_pointer
) is also a pointer type (according to typeid
) in the same context? The conflict arises between both overloads due to std::is_pointer
wrongly reporting p
as a non-pointer type. Also, when I replace the r-value reference with a standard reference in the first overload:
It doesn't conflict with the second overload anymore... I simply don't get what's going on. By the way, using the second overload yields (as would be expected):
#xA;Thanks for your help.
c++ - C++11 の右辺値とムーブ セマンティクスの混乱 (return ステートメント)
C++ 11 の右辺値参照と移動セマンティクスを理解しようとしています。
これらの例の違いは何ですか? また、ベクトル コピーを実行しないのはどれですか?
最初の例
2 番目の例
3 番目の例
c++ - std ::stringは右辺値*thisの"substr"をオーバーロードしてリソースを盗むことができますか?
std::string
割り当てられたメモリをから盗むことができる場合、のsubstr
操作は右辺値に対してはるかに効率的である可能性があることに気づきました*this
。
N3225の標準ライブラリには、次のメンバー関数宣言が含まれています。std::string
右辺値用に最適化されたものを実装できる実装は、substr
それをオーバーロードし、2つのバージョンを提供できますか?そのうちの1つは右辺値文字列のバッファーを再利用できますか?
*this
設定のメモリを移動元の状態に再利用して、右辺値バージョンを次のように実装できると思います*this
。
これは一般的な文字列の実装で効率的に機能しますか、それともハウスキーピングが多すぎますか?
c++ - Visual C ++ 2010、右辺値参照のバグ?
Visual C ++ 2010のバグですか、それとも正しい動作ですか?
関数f(T &&)は決して呼び出されるべきではないと思いましたが、T = int&で呼び出されます。出力:
アップデート1リファレンスとしてC++x0コンパイラを知っていますか?comeauオンラインテストドライブを試しましたが、r値参照をコンパイルできませんでした。
アップデート2の回避策(SFINAEを使用):
アップデート3一部のコンパイラは、関数テンプレートのインスタンス化がない場合でも、static_assert(false、 "no way")でトリガーします。回避策(@Johannes Schaubに感謝-litb)
また
c++11 - 右辺値を使用した算術式で「最適な」演算子のオーバーロード解決を実現するにはどうすればよいですか。
まず、過度に冗長な質問をお詫びします。問題を正確に要約する他の方法は考えられませんでした...次に実際の質問に移ります。
現在、C ++ 0x右辺値参照を実験しています...次のコードは、望ましくない動作を生成します。
結果は出力になります
結果を格納するための
新しい一時的なものを構築する結果を格納するために一時的な第1オペランドを 再利用
する結果を格納するために一時的な第1オペランドを再利用する結果を格納するための新しい一時的なものを構築する
私は次のようなものを望んでいましたが
constructing new temporary to store result
reusing temporary 1st operand to store result
reusing temporary 2nd operand to store result
reusing temporary 2nd operand to store result
After trying to re-enact what the compiler was doing (I'm using MinGW G++ 4.5.2 with option -std=c++0x in case it matters), it actually seems quite logical. The standard says that arithmetic operations of equal precedence are evaluated/grouped left-to-right (why I assumed right-to-left I don't know, I guess it's more intuitive to me). So what happened here is that the compiler evaluated the sub-expression (v3 + v4)
first (since it's in parentheses?), and then began matching the operations in the expression left-to-right against the operator overloads, resulting in a call to Vector4 operator + (const Vector4& other)
for the sub-expression v1 + v2
. If I want to avoid the unnecessary temporary, I'd have to make sure that no more than one lvalue operand appears to the immediate left of any parenthesized sub-expression, which is counter-intuitive to anyone using this "library" and innocently expecting optimal performance (as in minimizing the creation of temporaries).
(I'm aware that there's ambiguity in my code regarding operator + (Vector4&& v1, const Vector4& v2)
and operator + (Vector4&& other)
when (v3 + v4)
is to be added to the result of v1 + v2
, resulting in a warning. But it's harmless in my case and I don't want to add yet another overload for two rvalue reference operands - anyone know if there's a way to disable this warning in gcc?)
Long story short, my question boils down to: Is there any way or pattern (preferably compiler-independent) this vector class could be rewritten to enable arbitrary use of parentheses in expressions that still results in the "optimal" choice of operator overloads (optimal in terms of "performance", i.e. maximizing the binding to rvalue references)? Perhaps I'm asking for too much though and it's impossible... if so, then that's fine too. I just want to make sure I'm not missing anything.
Many thanks in advance
Addendum
First thanks to the quick responses I got, within minutes (!) - I really should have started posting here sooner...
It's becoming tedious replying in the comments, so I think a clarification of my intent with this class design is in order. Maybe you can point me to a fundamental conceptual flaw in my thought process if there is one.
You may notice that I don't hold any resources in the class like heap memory. Its members are only scalar types even. At first sight this makes it a suspect candidate for move-semantics based optimizations (see also this question that actually helped me a great deal grasping the concepts behind rvalue references).
However, since the classes this one is supposed to be a prototype for will be used in a performance-critical context (a 3D engine to be precise), I want to optimize every little thing possible. Low-complexity algorithms and maths-related techniques like look-up tables should of course make up the bulk of the optimizations as anything else would simply be addressing the symptoms and not eradicating the real reason for bad performance. I am well aware of that.
With that out of the way, my intent here is to optimize algebraic expressions with vectors and matrices that are essentially plain-old-data structs without pointers to data in them (mainly due to the performance drawbacks you get with data on the heap [having to dereference additional pointers, cache considerations etc.]).
I don't care about move-assignment or construction, I just don't want more temporaries being created during the evaluation of a complicated algebraic expression than absolutely necessary (usually just one or two, e.g. a matrix and a vector).
Those are my thoughts that might be erroneous. If they are, please correct me:
- To achieve this without relying on RVO, return-by-reference is necessary (again: keep in mind I don't have remote resources, only scalar data members).
- Returning by reference makes the function-call expression an lvalue, implying the returned object is not a temporary, which is bad, but returning by rvalue reference makes the function-call expression an xvalue (see 3.10.1), which is okay in the context of my approach (see 4)
- Returning by reference is dangerous, because of the possibly short lifetime of objects, but:
- temporaries are guaranteed to live until the end of the evaluation of the expression they were created in, therefore:
- making it safe to return by reference from those operators that take at least one rvalue-reference as their argument, if the object referenced by this rvalue reference argument is the one being returned by reference. Therefore:
- Any arbitrary expression that only employs binary operators can be evaluated by creating only one temporary when not more than one PoD-like type is involved, and the binary operations don't require a temporary by nature (like matrix multiplication)
(Another reason to return by rvalue-reference is because it behaves like returning by value in terms of rvalue-ness of the function-call expression; and it's required for the operator/function-call expression to be an rvalue in order to bind to subsequent calls to operators that take rvalue references. As stated in (2), calls to functions that return by reference are lvalues, and would therefore bind to operators with the signature T operator+(const T&, const T&)
, resulting in the creation of an unnecessary temporary)
I could achieve the desired performance by using a C-style approach of functions like add(Vector4 *result, Vector4 *v1, Vector4 *v2)
, but come on, we're living in the 21st century...
In summary, my goal is creating a vector class that achieves the same performance as the C-approach using overloaded operators. If that in itself is impossible, than I guess it can't be helped. But I'd appreciate if someone could explain to me why my approach is doomed to fail (the left-to-right operator evaluation issue that was the initial reason for my post aside, of course).
As a matter of fact, I've been using the "real" vector class this one is a simplification of for a while without any crashes or corrupted memory so far. And in fact, I never actually return local objects as references, so there shouldn't be any problems. I dare say what I'm doing is standard-compliant.
Any help on the original issue would of course be appreciated as well!
many thanks for all the patience again
c++ - 右辺値参照用のreference_wrapper<>はありますか?
どうすれば次のことができるのだろうか
右辺値参照を渡して、それを右辺値参照(おそらくラップされている)として呼び出しラッパーに格納するにはどうすればよいですか?std::reference_wrapper<>
に変換関数を持つようなクラスを手動で作成できることは知っていますがT&&
、それを避けて標準テクノロジを使用したいと思います。
AProgrammerが推奨するように実装しました。
今私は言うことができます
左辺値をに渡すmake_adv
と、入力引数を参照する左辺値として転送されるためstd::ref
、この場合は、の代わりに使用できます。
c++ - クラス、右辺値、および右辺値参照
左辺値はメモリの決定的な領域にバインドされた値ですが、右辺値は一時的な存在であり、必ずしもメモリの決定的な領域を参照するとは限らない式の値です。右辺値が予期される位置で左辺値が使用される場合は常に、コンパイラは左辺値から右辺値への変換を実行してから、評価を続行します。
http://www.eetimes.com/discussion/programming-pointers/4023341/Lvalues-and-Rvalues
一時的な (匿名の) クラス オブジェクトを構築するか、関数から一時的なクラス オブジェクトを返すときはいつでも、オブジェクトは一時的ですが、アドレス指定可能です。ただし、オブジェクトは依然として有効な右辺値です。これは、オブジェクトが a) アドレス指定可能な右辺値であるか、または b) コンパイラが左辺値の使用を想定しているときに、左辺値から右辺値に暗黙的に変換されていることを意味します。
例えば:
また、関数によって返される一時オブジェクト(次の場合) は、次のコード セグメントのように左辺値であることもわかっています。a
次の出力が得られます。
int conversion ctor
lvalue copy ctor
ret_a
実引数を使用した関数の呼び出しが、値 5 で関数の仮引数を構築A(5)
する変換コンストラクターを呼び出すことを示します。A::A(int)
a
関数の実行が完了すると、 を引数として使用して一時A
オブジェクトを作成し、 を呼び出します。ただし、オーバーロードされたコンストラクターのリストから削除した場合、返された一時オブジェクトは引き続き右辺値参照コンストラクターと一致します。a
A::A(A&)
A::A(A&)
A::A(A&&)
これは私がよく理解していないことです:オブジェクトa
が右辺値参照と左辺値参照の両方にどのように一致するのでしょうか? A::A(A&)
の方がより適切に一致することは明らかですA::A(A&&)
(したがってa
、左辺値である必要があります)。ただし、仮引数a
が左辺値である場合、右辺値参照は左辺値に初期化できないため、 への呼び出しと一致することはできませんA::A(A&&)
。コンパイラが左辺値から右辺値への変換を行っている場合、それは簡単です。'A' から 'A&' への変換も些細なことであり、両方の関数が同一の暗黙的な変換シーケンス ランクを持つ必要があるため、オーバーロードされた関数にA::A(A&)
との両方がある場合、コンパイラは最適な関数を推測できないはずです。A::A(A&&)
候補セット。
さらに、質問(以前に尋ねたもの)は次のとおりです。
特定のオブジェクトが右辺値参照と左辺値参照の両方に一致するにはどうすればよいですか?