問題タブ [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++ - 推論されていないコンテキストを持つ関数テンプレートを使用した半順序
別の質問を読んでいるときに、半順序の問題が発生しました。これを次のテストケースに切り詰めました。
どちらの関数テンプレートでも、オーバーロード解決に入る特殊化の関数タイプはですvoid(int, void*)
。しかし、半順序(comeauとGCCによる)は、2番目のテンプレートがより特殊化されていることを示しています。しかし、なぜ?
半順序を見て、質問がある場所を示しましょう。に従ってQ
半順序を決定するために使用される一意の構成タイプである可能性があり14.5.5.2
ます。
T1
(Qが挿入された)の変換されたパラメータリスト:(Q, typename Const<Q>::type*)
。引数のタイプは次のとおりですAT
=(Q, void*)
T2
(Qが挿入された)の変換されたパラメータリスト:BT
=(Q, void*)
、これは引数のタイプでもあります。- 変換されていないパラメータリスト
T1
:(T, typename Const<T>::type*)
- 変換されていないパラメータリスト
T2
:(T, void*)
C ++ 03はこれを過小評価しているので、私はいくつかの欠陥レポートで読んだ意図を使用しました。上記のT1
(私が呼び出した)の変換されたパラメータリストは、 「関数呼び出しからテンプレート引数を推測する」AT
の引数リストとして使用されます。14.8.2.1
14.8.2.1
AT
変換する必要も、それ自体を変換する必要もありBT
ません(たとえば、参照宣言子を削除するなど)。これは、 /ペア14.8.2.4
ごとに独立して型演繹を行います。A
P
AT
に対してT2
:。ここでの唯一のテンプレートパラメータであり、それはである必要があります。型の演繹は、に対して自明に成功します。{
(Q, T)
,
(void*, void*)
}
T
T
Q
AT
T2
BT
に対してT1
:。それもここにあります。は推論されていないコンテキストであるため、何も推論するために使用されることはありません。{
(Q, T)
,
(void*, typename Const<T>::type*)
}
T
Q
typename Const<T>::type*
これが私の最初の質問です:これT
は最初のパラメータに推定された値を使用しますか?答えが「いいえ」の場合、最初のテンプレートはより特殊化されています。GCCとComeauの両方が、2番目のテンプレートはより特殊化されていると言っており、それらが間違っているとは思わないため、これは当てはまりません。したがって、「はい」と想定し、に挿入void*
しT
ます。段落(14.8.2.4
)には、「推論はペアごとに個別に実行され、結果が結合されます」および「ただし、特定のコンテキストでは、値は型の推論に関与せず、代わりに推定されたテンプレート引数の値を使用します」と記載されています。他の場所または明示的に指定されています。」これも「はい」のように聞こえます。
したがって、すべてのA / Pペアについて、控除も成功します。現在、各テンプレートは少なくとも他のテンプレートと同じように特殊化されています。これは、控除が暗黙の変換にも依存せず、両方向で成功したためです。結果として、呼び出しはあいまいになるはずです。
それで私の2番目の質問:では、なぜ実装は2番目のテンプレートがより専門的であると言うのですか?どの点を見落としましたか?
編集:明示的な特殊化とインスタンス化をテストしましたが、最近のGCCバージョン(4.4
)では、特殊化への参照があいまいであると教えてくれましたが、古いバージョンのGCC(4.1
)ではそのあいまいさのエラーは発生しません。これは、最近のGCCバージョンでは、関数テンプレートの半順序に一貫性がないことを示しています。
c++ - dynamic_cast でのテンプレート推定
次のように定義されたクラスがあります。
関数内で私はこれをやっています:
タイプを解決しCometWidget
、準拠して正しく実行します。
コードはCometWidget
クラス内で実行されます。
一体どうしてこれが起こるのですか?
どうしてこんなことに?コンパイルする必要がありますか?
c++ - 戻り値の型に基づく関数のテンプレート推定?
テンプレート推論を使用して、次のことを達成できるようにしたいと思います。
(私が現在持っているもの)の代わりに:
私の現在の割り当て関数は次のようになります。
<A>
これは余分なとをノックオフすることは可能でしょう<B>
か?
c++ - const T への shared_ptr による C++ テンプレートのインスタンス化
クラスがあるとします
以下はコンパイルされません。
コンパイラ エラーは次のとおりです。
コンパイラは、最初の引数をstd::tr1::shared_ptr<std::vector<float> >
作成
できませんでした。std::tr1::shared_ptr<const std::vector<float> >
ただし、2 番目の引数 (非テンプレート引数) については可能です。
これに対する 1 つの解決策は、呼び出しを f() に変更して、このように呼び出すことf<float>(...)
です。
別の解決策は、v1 を shared_ptr として宣言してconst vector<float>.
- ここでテンプレートのインスタンス化の動作が非常に異なるのはなぜですか?
- メソッドへの as 引数を持つことについての私の理解は
shared_ptr<const T>
、メソッドがshared_ptr
が指しているものを変更できないということです。shared_ptr
s を生のポインタに変更し、を への生のポインタとして変更するとv1
、コードは正常にコンパイルされます。テンプレート演繹を破るのは sについて何ですか?v2
vectors
shared_ptr
c++ - テンプレート関数呼び出し時の C++ テンプレート推定
FastDelegate
http://www.codeproject.com/KB/cpp/FastDelegate.aspxを参照していますが、関連しているとは思いません。
次のようなコードがあり、エラーが発生しました。
を次のように変更した場合main()
:
また:
fdGetter からMakeProp()
取得する必要があると思います(これは、自動的にコンストラクターと呼ばれるよりも. しかし、そうではありませんでした. なぜ?T
int
FastDelegate1<int>
PS getter と setter を に保存したいと思いProp
ます。このアプローチに関する提案は大歓迎です。関数で引数を渡すときに FastDelegate* のインスタンスをコピーするのは悪いことかもしれません。
c++ - 同時に転送しながら、元のタイプの知識を推測する
要約:最終的に、呼び出された正確な型を推測し、それらを転送するタプルを取得する関数を作成したいと思います(その型は、関数が呼び出された正確な型とは異なります)。
与えられた関数への引数のタイプを推測することで「知る」ことを試みながら、同時にそれらを転送しようとして立ち往生しています。私はこれがどのように機能するかについて重要な何かを見逃しているかもしれないと思います。
私が見たいのは、私の関数(egg1
またはg2
)が呼び出されたときに、元のタイプint,double,void*,std::string&,const char*
と転送されたarugmentsの両方を認識して使用できるシナリオです。
g1
この場合、または内からこの情報を見つけることができないようですg2
。(意図的に、型を出力するための)リンカエラーは、次のように表示されg1
ます。
とでg2
:
ここで得られないことが2つあります。
印刷された(リンカーエラーを介した)タイプのいずれも、実際に渡したものと一致しないのはなぜですか?(
int,double,void*,std::string&,const char
)。私が実際に渡されたものを推測できますか?できれば「自然な」構文を使用します。つまり、すべてを1回だけ、明示的に何も書き出さないようにします。私は明示的に書くことができます:しかし、それは控えめに言っても「扱いにくい」です!
関数に
g1
存在&&
する場合、署名宣言はテンプレートパラメータArgs
自体の型を変更するようです。それを以下と比較してください:または:
次のいずれかを使用します。
のタイプは変更されません
T
。変更しないのに、なぜそれ自体&&
のタイプを変更するのですか?T
&
c++ - 適切な value_type を取得する
私のクラスにはメンバーがいます:
今、メモリの最初の要素にあるものを返すfncが必要ですが、後でこの目的のために別のタイプを使用することにした場合に備えて、戻り値の型として指定したくないstd::string
ので、これを試しましたが、そうではありません仕事:
最も一般的な方法で戻り値の型を指定する方法はありますか?
c++ - 非推定コンテキストでのテンプレート引数推定の回避策
次のコードを検討してください。
これは、推定されないコンテキストtypename outer<T>::inner
であるため (ここで説明されているように)、コンパイルされません。つまり、コンパイラはテンプレート引数の型を推定できません (理由については、この回答をお読みください)。私が見ているように、それを機能させるには2つのオプションがあります。
inner
の外側に移動outer
して、クラス テンプレートにします。コードの使用への影響が小さいため、私はこれを好みます。to_string
-メソッドを innerに追加します。
これに対する他の解決策はありますか (コードを使用する際に醜い構文にならないようにします)。
c++ - コンパイルに失敗せずに型が不完全であるかどうかを推測することは可能ですか?
sizeof(complete_type)が実際のsizeofを返し、sizeof(incomplete_type)がちょうど0になるような動作を実現したい
タイプごとの記述構造を持つIPC(プロセス間)通信の拡張実行時タイプ情報を提供するためにこれが必要です。
私のシステムにクラスMyOnlyDeclaredClassのようなものが入ると、問題が発生します。サイズがわからないという理由で、コンパイルエラーが発生しました。
boost type_traits http://www.boost.org/doc/libs/1_48_0/libs/type_traits/doc/html/index.htmlは、多くのコンパイル時クラスを提案していますが、「is_incomplete」はありません。
興味深いコンパイラは、VS2008、VS2010、clang 3、gcc-4.6、gcc-4.7です。
c++ - `std::reference_wrapper`s でテンプレート インスタンスを推定できないのはなぜですか?
タイプ のオブジェクトがありT
、それを参照ラッパーに入れたいとします。
if (p < q)
参照ラッパーにはラップされた型への変換があるため、これで簡単に言うことができます。すべてが順調で、参照ラッパーのコレクションを元のオブジェクトと同じように処理できます。
(以下にリンクされている質問が示すように、これは既存のコレクションの代替ビューを生成する便利な方法であり、元のコレクションとの更新の整合性を維持するだけでなく、完全なコピーのコストを負担することなく自由に再配置できます。 )
ただし、一部のクラスではこれが機能しません。
私の回避策は、この回答のように述語を定義することです *; しかし、私の質問は次のとおりです。
演算子を参照ラッパーに適用し、ラップされた型の演算子を透過的に使用できるのはなぜですか? なぜ失敗するのstd::string
ですか?std::string
テンプレートインスタンスであるという事実と何の関係があるのでしょうか?
*)更新:回答に照らして、使用std::less<T>()
は一般的な解決策のようです。