問題タブ [template-argument-deduction]
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++ - C++11、14、または 17 は、decltype() から引数だけを取得する方法を提供しますか?
この質問は、「 decltype(someFunction) から引数の型リストだけを抽出する」と非常によく似ています。そこにある答えが、私が意図していることに対して機能するかどうかはわかりません。関数ポインターのテンプレート引数 ( whistle )の型に基づいてランタイム引数の型を推測するテンプレート関数を作成できるようにしたいと考えています。
ユースケースの例として、LD_PRELOAD でロードされた shim ライブラリを使用して、ストレートな C POSIX ファイル I/O を計測したいとします。fopen、fread、fwrite、fclose 用に個別のラッパーを作成することもできますが、これらのラッパーがすべて同様の処理を行う場合、共通の動作をキャプチャするテンプレートを定義できればよいと思いませんか?
定型文がどれだけ含まれているかを示すテンプレートを使用しない部分的な例:
可変個引数テンプレート関数を使用して、いくつかのコードを保存できます。
ただし、テンプレート パラメーターのリストでこれらの冗長な型をすべて渡すことを回避できる何らかの方法が必要です。私がやりたいことは、まだ有効な構文が見つからないことです (std::result_of の反対のような std::arguments_of と呼ぶものが存在すると仮定します):
C++11、14、または 17 でこれを行う有効な方法はありますか? どのように、またはそうでない場合、なぜですか?
c++ - 可変個引数関数ポインタ パラメータのテンプレート引数推定 - あいまいなケースの処理
次のコードを検討してください。
意図は、本体の各行をmain()
個別に試すことです。私の予想では、4 つの呼び出しはすべてあいまいであり、コンパイラ エラーが発生するだろうということでした。
私はコードをテストしました:
- Clang 3.6.0 と GCC 4.9.2 の両方で
-Wall -Wextra -pedantic -std=c++14
(-std=c++1y
for GCC) を使用 - エラー メッセージの文言のわずかな違いを除いて、これらすべてのケースで同じ動作。 - Visual C++ 2013 Update 4 と Visual C++ 2015 CTP6 - これも同じ動作なので、今後は "MSVC" と呼びます。
Clang と GCC:
#1
: コンパイラ エラーです。紛らわしいメッセージが表示されます。基本的にはno overload of 'f' matching 'void (*)()'
. 何?no-param 宣言はどこから来たのですか?#3
: コンパイラ エラー、別の紛らわしいメッセージ:couldn't infer template argument 'T'
。そこで失敗する可能性のあるすべてのことの中で、の引数を推測することはT
、私が期待する最後のものになるでしょう...#2
and#4
: エラーも警告もなくコンパイルされ、最初のオーバーロードが選択されます。
4 つのケースすべてで、オーバーロードの 1 つ (いずれか 1 つ) を削除すると、コードは正常にコンパイルされ、残りの関数が選択されます。これは、Clang と GCC の不一致のように見えます: 結局のところ、両方のオーバーロードで別々に推定が成功した場合、ケース#2
と#4
? 両者は完全に一致していませんか?
さて、MSVC:
#1
、#3
および#4
: コンパイラ エラー、適切なメッセージ:cannot deduce template argument as function argument is ambiguous
。今、それが私が話していることです!ちょっと待って...#2
: エラーも警告もなくコンパイルされ、最初のオーバーロードが選択されます。2 つのオーバーロードを別々に試してみると、最初の 1 つだけが一致します。2 番目のものはエラーを生成します:cannot convert argument 1 from 'void (*)(int,short)' to 'void (*)(int)'
. もうあまり良くありません。
case で何を探しているかを明確にするために#2
、これは標準 (N4296、C++14 final 後の最初のドラフト) が [14.8.1p9] で述べていることです。
テンプレート引数推定は、明示的に指定されたテンプレート引数がシーケンスに含まれている場合でも、テンプレート パラメーター パックに対応するテンプレート引数のシーケンスを拡張できます。
この部分は MSVC ではうまく機能しないようで、 の最初のオーバーロードを選択します#2
。
これまでのところ、MSVC は完全に正しいとは言えませんが、少なくとも比較的一貫しているようです。Clang と GCC はどうなっていますか? それぞれの場合の標準に従った正しい動作は何ですか?
c++ - 関数ポインタ参照でテンプレート推定が機能しない
私は回り道を使用していますが、それらが使用するキャストが非常に醜いことがわかったので、キャストを行うためにいくつかのテンプレート関数を作成しました。
これにより、次の呼び出しを実行できます。
fnPtrRefToVoidPtrRef
しかし、2 つの関数名を1 つの名前に統合できないかと考えていfnPtrToVoidPtr
ました。
テンプレートの引数を推測できないため、次の操作は機能しません。
次のエラーが発生します。
私の元の関数を使用すると、これは正常に機能します。
ただし、これに変更fnPtrRefToVoidPtrRef
すると:
次のエラーが表示されます。
テンプレート推論ができないのは、それが同じ(または変換可能?)タイプであると認識しない理由のようです。C++ を取得して関数ポインタを適切に推測する方法はありますか?
c++ - テンプレート引数としての自動
なぜ正しくないのですか?auto を char として推測する問題は何ですか?
c++ - 可変個引数テンプレートの推定コンテキストではありません
次のコードは、私が知っているように、「推測されたコンテキストではない」(またはそうでない) 必要があります。
しかし、g++ 4.9 は in の両方のインスタンス化のためにそれをコンパイルしますf
...main
誰か説明できますか?
c++ - C++03 でのテンプレート関数の戻り値の型推定
C++03 で以下を実装したいと思います。
convert
を明示的に指定せずに呼び出したい場合を除きますT1
。それ、どうやったら出来るの?
c++ - C++、カスタム プレースホルダーを関数の引数と一致させる
私は次のことを行うコードを書き込もうとしています:カスタムバインド関数の呼び出しがあるとしましょう
そして私たちが持った後
関数 some_func:
bind_obj(...) など、実際の関数呼び出しで提供される引数とプレースホルダーを一致させるにはどうすればよいでしょうか?
つまり、std::tuple (ここでは引数とプレースホルダー) と variadic pack (関数の引数) を反復して次のことを行うことは可能ですか?
- 関数 some_func の戻り値の型を推測します。
- some_func() 呼び出しでさらに使用するために正しい std::tuple を作成しますか?
ブーストと std::functional を使用せずにこれを実行しようとしています。私の主な問題は、実行時に引数を使用してタプルを構築する方法(すべてのプレースホルダーが正しく置き換えられた場所)と戻り値の型を推測する方法がわからないことだと思います。
STL "functional.h" で _Mu テンプレート構造を見ましたが、複雑すぎてオーバーロードされているように見えます。
c++ - 関数パラメーターが T への const 参照である場合、T のテンプレート パラメーター推定が配列要素の constness を「スキップ」するのはなぜですか?
これらの定義を考えてみましょう:
constへのポインタ付き
次のステートメントが実行された場合:
出力は次のとおりです。
したがってT
、実際には定数整数へのポインターとして推定されます。引数が const への参照であるという事実は、推論を変更しません。これは、ポインターの constness が低レベルであるため、予想されることです。
しかし、constの配列で
それにもかかわらず、次のステートメントが実行された場合:
出力は次のとおりです。
したがって、実際には 3 つの非const 整数T
の配列として推定されます。引数が const への参照であるという事実は、配列要素に滑り込んでいるかのように、推定を変更します。const
実際、CL の 18 までのバージョンはT
、3 つの const 整数の配列が標準であると予想していたので推測していましたが、v19 以降、GCC と Clang が行っていること (つまり、非const として推測) に収束したようです。
したがって、後者の動作が標準であると想定していますが、その根拠は何でしたか? ポインタのように振る舞わないのは驚くべきことかもしれません。
編集:ディップコメントに続いて、この動作に関連するCWGの問題へのポインタ、彼が実際にこの回答にコメントとして投稿したポインタをここに報告します(実際にこの新しい質問を提起した回答... C ++は深いトンネルのように感じます)