問題タブ [expression-templates]
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++ - 比較演算子を使用する場合は、複数の値を確認してください
私は常に、比較ステートメント、つまりX == Y
またはX != Y
がフォーマットであり、ステートメントを&&
またはでチェーンするという印象を受けてきました||
。
X == (Y || Z)
代わりに書く方法はありませんかX == Y || X == Z
?
編集:これをきれいに行うことは不可能であることが確立されているので、他にどのようにそれを行うことができますか?
c++ - Intel C++ コンパイラは深いテンプレートを処理できませんか?
marrayライブラリを使用した C++ のプロジェクトがあります。今のところ、Windows 7 x64 上の MinGW g++ 4.7 および msvc2010 で、また Linux Mint x64 上の g++ 4.7 で、非常にうまくコンパイルおよび実行されます。Linux 用の Intel C++ コンパイラ v. 12.1.4 を試してみることにしました。コードをコンパイルすることはできましたが、式テンプレート (3 つの項すべてが行列である c = a + b など) に悩まされている行を実行しようとすると、セグメンテーション違反で失敗します。この問題は、アプリのデバッグ バージョンとリリース バージョンの両方に影響します。
また、marray ライブラリーの単体テストとチュートリアル・コードをコンパイルしようとしましたが、インテル C++ はコードをコンパイルしますが、式テンプレートがある場合は実行に失敗します。インテル® C++ は深いテンプレートで本当に悪いのでしょうか? それとも何か足りないのでしょうか? テンプレート式を機能させるには、特別なコンパイラ フラグを設定する必要がありますか? それとも、一般的な式テンプレートの手法ではなく、使用している特定のライブラリに何か問題があるのでしょうか?
また、 -ftemplate-depth- nフラグをnにさまざまな値を使用して10^10 という途方もなく大きな値まで設定しようとしましたが、セグメンテーション違反なしでアプリも marray ユニット テスト/チュートリアルも実行できませんでした。
Upd .:これは、デバッグ モードで icpc を使用してコンパイルされた前述のライブラリからの tutorial-marray の gdb ログです。
問題は一般に式テンプレートの手法に起因するものではないようです。数値を使用した配列演算は正常に機能します。ある配列を別の配列に追加しようとすると、問題が発生します。
更新。2:実際には、全体がここで言及されている問題と非常によく似ています。解決策は、演算子 E&() { return static_cast(*this); を書き直すことです。} E& get_ref() { return static_cast(*this); のようなものに const参照についても同じです。もちろん、コード内でのこれらの使用方法も変更してください。早速試して結果を報告します。
c++ - 式テンプレートとC++11
式テンプレートの1つの特定の利点を見てみましょう。ETを使用すると、次のようなオーバーロードされた演算子で発生する、メモリ内のベクトルサイズの一時的なものを回避できます。
C ++ 11では、この関数のreturnステートメントは移動セマンティクスを適用します。ベクトルのコピーはありません。それは勝利です。
しかし、私が次のような単純な表現を見ると
上記の関数は(両方に対してoperator+
)2回呼び出されますが、最終的な割り当ては移動セマンティクスで実行できます。
合計2つのループが実行されます。一時的に出して、すぐに読み返すという意味です。大きなベクトルの場合、これはキャッシュから外れます。これは、式テンプレートよりも悪いです。彼らはたった1つのループですべてを行うことができます。ETは、次と同等の上記のコードを実行できます。
ラムダと移動セマンティクスまたはその他の新機能を組み合わせてETと同じくらいうまくいくかどうか疑問に思いました。何かご意見は?
編集:
基本的に、コンパイラはET手法を使用して、型システムを使用した代数式に似た解析ツリーを構築します。このツリーは、内部ノードとリーフノードで構成されています。内部ノードは操作(加算、乗算など)を表し、リーフノードはデータオブジェクトへの参照を表します。
計算プロセス全体をスタックマシンのように考えてみました。操作スタックから操作を取得し、引数スタックから次の引数を取得して、操作を評価します。結果をスタックに戻し、操作を待機します。
これらの2つの異なるオブジェクト(操作スタックとデータリーフスタック)を表すstd::tuple
ために、操作用の
aとデータリーフ用のaをにバンドルしstd::tuple
ましたstd::pair<>
。最初はを使用しましたstd:vector
が、実行時のオーバーヘッドが発生しました。
プロセス全体は2つのフェーズで行われます。スタックマシンの初期化では、操作と引数のスタックが初期化されます。そして、ペアのコンテナをベクトルに割り当てることによってトリガーされる評価フェーズ。
Vec
プライベートarray<int,5>
(ペイロード)を保持し、「式」を受け取るオーバーロードされた代入演算子を特徴とするクラスを作成しました。
グローバルoperator*
は、takeingと "expression"のすべての組み合わせでオーバーロードされ
Vec
、がだけではない場合にも正しい処理を可能にしますa*b
。imull
(注意してください、私はこの教育的な例を乗算に切り替えました-基本的にはアセンブラーですばやく見つけるためです。)
Vec
評価を開始する前に最初に行うことは、関連するオブジェクトから値を「抽出」し、引数スタックを初期化することです。これは、インデックス付け可能なベクトルとインデックス付け不可能な結果など、さまざまな種類のオブジェクトが存在しないようにするために必要でした。これが
Extractor
目的です。繰り返しになりますが、可変個引数テンプレートが使用されます。この場合、実行時のオーバーヘッドは発生しません(これはすべてコンパイル時に行われます)。
すべてが機能します。式は適切に評価されます(追加も追加しましたが、コードに合わせるためにここでは省略しています)。以下に、アセンブラの出力を示します。まさにあなたが望むように、生の計算:ET技術と同等。
アップショット。C ++ 11の新しい言語機能は、(テンプレートメタプログラミングとともに)コンパイル時の計算の領域を開く可変個引数テンプレートを提供します。ここでは、可変個引数テンプレートの利点を使用して、従来のET手法と同じくらい優れたコードを生成する方法を示しました。
で生成されたアセンブラg++-4.6 -O3
(コンパイラがコンパイル時にすべてを計算せず、実際にインスタンスが表示されるように、実行時の依存関係をベクトルの初期化にimull
含める必要がありました。)
c++ - std :: basic_stringが式テンプレートによる連結をサポートしないのはなぜですか?
QtQString
は連結できますoperator%
。これは、式テンプレートを使用して、結果の文字列のサイズを事前に計算し、へのいくつかの連鎖呼び出しを最適化しoperator+
ます。詳細については、私のこの質問を参照してください。
なぜstd::basic_string
同様の構成を採用していないのですか?これはC++11でも許可されていますか?私は利点だけを見て、明らかにABIの互換性は、ライブラリの実装者が望むときに壊すことができます(そして、C ++11はlibstdc++に対しても正当な理由を提供しました)。
c++ - 式テンプレートの問題を含む c++ マトリックス
行列を扱う学校のプロジェクトを作成する必要があります。Visual Studio 2010 では、すべて正常に動作します。テスターサーバーには、「matrix_base」とメイン関数があります。次に例を示します。
サーバーのコンパイラは、-static -O2 パラメーターを持つ g++ です。そして、次のようなエラーが発生します。
/var/www/F/I704e/3/1/testzt1.cpp: 関数 'int main()' 内:
/var/www/F/I704e/3/1/testzt1.cpp:42: エラー: 'operator+(const my_matrix&, const my_matrixAdd&) の 'operator+' に一致しません [with T = int, int N = 5, int M = 3, LeftOp = my_matrix, RightOp = my_matrix](((const my_matrixAdd, my_matrix >&)((const my_matrixAdd, my_matrix >*)(& operator+(const my_matrix&, const my_matrix&) [with T = int, int N = 5 , int M = 3](((const my_matrix&)((const my_matrix*)(& mtx3)))))))) + operator+(const my_matrixAdd&, const my_matrix&) [with T = int, int N = 5, int M = 3, LeftOp = my_matrix, RightOp = my_matrix](((const my_matrix&)((const my_matrix*)(& mtx6))))'</p>
そして次のように:
/var/www/F/I704e/3/1/teszt1.cpp:6 から含まれるファイル:
/var/www/Hallg/I704e/3/h145172/7/feladat.cpp: 関数 'my_matrixAdd、my_matrixAdd > operator+(const my_matrixAdd&、const my_matrixAdd&) [with T = int、int N = 5、int M = 3、 LeftOp = my_matrix, RightOp = my_matrix]':
私を助けてください!ありがとう!
c++ - C++ 関数のオーバーロード、式テンプレート、名前空間
式テンプレートと演算子/関数のオーバーロードに基づく自動微分ツールを開発しています。たとえば、テンプレートstd::max関数は正常にオーバーロードされました。
しかし、次のようなコードで
名前空間が省略された場合はstd::が使用され、その他の一部の関数ではead::が使用されます。max 関数など、常に ead:: 名前空間を選択するようにコンパイラに強制するトリックはありますか? (C++11 機能なしでお願いします) なぜコンパイラは std::max の方が適していると考えるのですか? 関数名の前にead::
を書くことは大したことではないことはわかっていますが、ユーザーが入力する手間を省きたいのです。
c++ - Boost Phoenix のネストされた let ブロック内の変数の隠蔽
「内部」ローカル変数が「外部」ローカル変数を隠している場合、Boost Phoenix のネストされた let ブロックで問題が発生します。ドキュメントhereの「可視性」の例でも、ここに示されています。
次のようなエラーが表示されます。
フェニックスのインナーレットブロックのスコープ内でそのような変数を「シャドウ」する方法を知っている人はいますか? 現在、GCC バージョン 4.8 スナップショットで Ubuntu 13.04 を使用しています。クラン 3.2; ブースト 1.49; Boost 1.53も。