問題タブ [function-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++ - C++ 関数ポインタの問題
何らかの理由で、この関数へのポインターを varadic 関数に渡そうとすると、次のエラーが発生します。
テンプレート関数にはオーバーロードがなく、テンプレートパラメーターは明示的に定義されているため、どの関数にポインターを渡すかについては疑問がありません...
引数変換関数ごとに多くのバージョンを作成する必要はありませんが、エラーが発生した場合に例外に引数番号を含めることができる方法はありますか? (引数番号をパラメーターとして渡す方法がさらに良いので、dllに関数の複数のコピーがありません。)
EDIT:これもコンパイルエラーになるようです。テンプレート関数への関数ポインタを作成する方法はありませんか、それとも通常の関数とは異なる方法で行う必要がありますか?
関数は次のように宣言されます。
EDIT2:オペレーターのアドレスを追加すると、さらに別の異なるエラーが発生しました...
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++ - デフォルトのパラメーター値を必要とするテンプレート関数の推奨設計は何ですか?
私は現在、関数テンプレートでいっぱいの API の整理に取り組んでおり、次のコードを書きたいという強い願望がありました。
このテンプレートを呼び出すときは、次のようにしたいと思います。
残念ながら、コンパイラはオプションのパラメータの型を推測できないため、2 番目の呼び出しはコンパイルされません。これは残念なことです。なぜなら、私はパラメーターの型が何であるかはあまり気にせず、その値が NULL であることを気にしているからです。また、3 回目の呼び出しのルートは可読性を損なうので避けたいと思います。
これにより、テンプレート引数にデフォルトの型を持たせようとしましたが、V
(少なくとも VC++ 9.0 を使用して) 関数テンプレートの引数にデフォルトの型を適用できないため、これも機能しません。
私の残りの唯一のオプションはdoWork
、テンプレート引数について何も知らない のオーバーロードを導入することV
です。
これは、この問題を解決するための最良のアプローチですか? 私が見る唯一の欠点は、関数テンプレートに適切なデフォルトを持つ多くのパラメーターが含まれている場合、多くの単純な転送関数を導入できる可能性があることです。
c++ - 次の例で、コンパイラが関数テンプレートのオーバーロードを選択しないのはなぜですか?
次の関数テンプレートがあるとします。
次のコードが常にオーバーロード #2 ではなくオーバーロード #1 を呼び出すのはなぜですか?
f
の 2 番目のパラメーターが の派生型であることを考えると、Base
オーバーロード #1 のジェネリック型よりも一致するオーバーロード #2 をコンパイラが選択することを期待していました。
これらの関数を書き直して、ユーザーがmain
関数に表示されるようにコードを記述できるようにするために使用できる手法はありますか (つまり、引数の型のコンパイラ推定を利用します)。
c++ - 指定されたクラス名で未知のクラスのオブジェクトを取得する方法
どのタイプのオブジェクトを割り当てる必要があるかを実行時に決定する方法を探しています( type の特定のクラス名に基づいてconst char*
)。
もちろん、最も簡単な方法はif
s / else if
sの負荷を使用することですが、100を超える異なるクラスがあり(少なくともそれらはすべて1つの基本クラスから派生しています)、新しいクラスをかなり定期的に追加する必要があるため、適用できないようです同じように。
私はすでに最初のドラフトを思いつきましたが、残念ながらまだコンパイルされていません (mingw & g++ 4.4)
しかし、それsizeof...(TArgs)>0
はgccget_classobject<TBase,const char*>(const char*)
が失敗するコードを生成しようとするのを止めません
これを修正する方法、または他のアイデアはありますか?ありがとう。
編集:私はそれを解決しました:
編集 興味のある読者へ:
上記の実装はコンパイラにまったく依存していないことに注意してください。の出力は、typeif(sometype).name()
コンパイラ/実装固有です。すべての派生クラス内で変数または関数を使用するstatic const char* name
と、これは修正されますが、多くの作業が追加されます (もちろん、これにはマクロを使用できますが、既にマクロを使用している場合は、別のオブジェクト ファクトリ メソッドを使用することもできます)。
templates - テンプレート(非メンバー)関数でテンプレートクラスのtypedefを使用する
以下はコンパイルに失敗します(とにかく、Linux上のgcc 4.2.1で):
問題はこの行にあります:
...そしてコンパイラはこの不満を言います:
foo.c:関数内'void templated()':
foo.c:22:エラー:予期される `; ' 「バー」の前</p>
通常、型が宣言されていないときにこれが表示されますが、私が知る限り、Foo <T> :: FooTypeはtemplated()内で完全に有効である必要があります。
c++ - クラス T in c++ (定義)
C++ でクラス T を使用する利点の 1 つは、関数内のデータ型が他の関数 (たとえば int main など) で定義されている場合に、それらのデータ型を再定義する時間を短縮できることです。
したがって、この場合、クラス T を使用しない場合、データ型ごとに対応するデータ型条件を追加する必要があります。つまり、int の場合は別の if ステートメントのセットを、float の場合は別のセットを追加する必要があります。
私は正しいですか?
c++ - 関数テンプレートのオーバーロード:リンクエラー
次のように「display」メソッドをオーバーロードしようとしています。
次に、unsigned char*im1およびchar*im2を使用してテンプレートを呼び出しています。
これは正常にコンパイルされますが、次のリンクエラー「未解決の外部シンボル」が表示されます。
何が悪かったのかわかりません!
c++ - 関数のテンプレート
function のテンプレートを作成するように言われました。これには 4 つの引数が必要です。
- ポインタ
- 参照
- 配列へのポインタ
- 関数へのポインタ
このタスクの実行方法 やってみた :
これにより、「一致する関数がありません。「pf」の場合だと思います。また、pf内で何を渡すかを制御できないか、間違っていますか?