問題タブ [sfinae]
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++ - enumテンプレートパラメータでSFINAEが失敗する
誰かが次の動作を説明できますか (私は Visual Studio 2010 を使用しています)。
ヘッダ:
ソース:
これが与えるコンパイラ
と
しかし、関数テンプレート パラメーターを列挙型 WeekDay から int に変更すると、正常にコンパイルされます。
また、通常の関数テンプレートの特殊化も問題なく機能します。驚くことではありません。
さらに奇妙なことに、ソース ファイルを MONDAY または TUESDAY 以外の WeekDay を使用するように変更するbool b = goToWork<THURSDAY>();
と、エラーは次のように変わります。
編集:おそらく誰かが別のコンパイラ(Visual Studio 2010以外)でこれをテストして、同じことが起こるかどうかを確認できます.
編集: この動作の新しい「興味深い」側面を見つけました。つまり、テンプレート パラメーターと==
and!=
演算子の直接比較をヘルパー構造体テンプレートとの比較に変更すると、正常に動作します。
編集: ところで、私はバグ レポートを作成しましたが、これは Microsoft からの回答です: -回避策が利用可能です。Visual Studio の次のリリースではこれを修正できません。回避策は、テンプレート パラメーターの型を int に変更することです。"
(「このリリース」は Visual Studio 2010 を指していると思います)
c++ - クラスにオーバーロードされた関数があるかどうかの検出が Comeau コンパイラで失敗する
SFINAE を使用して、クラスに特定の型を取るオーバーロードされたメンバー関数があるかどうかを検出しようとしています。私が持っているコードは、Visual Studio と GCC で正しく動作するようですが、Comeau オンライン コンパイラを使用してコンパイルしません。
私が使用しているコードは次のとおりです。
エラー メッセージは次のとおりです。関数テンプレート「CallFunc」のインスタンスが引数リストと一致しません。HasFunc::Has が true であるべき int と float に対して false のようです。
これは Comeau コンパイラのバグですか? 私は標準的ではないことをしていますか?もしそうなら、それを修正するために何をする必要がありますか?
アップデート
これがバグである場合、それを回避するために何かできることはありますか? &TestClass::Func で static_cast を使用しようとしましたが、それが不可能であるか、コンパイルできなかったため正しい構文を取得できませんでした。
それが解決策でない場合、問題を回避するために TestClass または HasFunc に変更を加えることはできますか?
c++ - 演繹中に関数のアドレスを解決できない場合、それはSFINAEまたはコンパイラエラーですか?
C ++ 0xでは、SFINAEルールが簡略化され、演繹の「即時コンテキスト」で発生する無効な式または型がコンパイラエラーではなく、演繹失敗(SFINAE)になります。
私の質問はこれです:
私がオーバーロードされた関数のアドレスを取り、それを解決できない場合、その失敗は演繹の直接の文脈でですか?
(つまり、ハードエラーですか、それとも解決できない場合はSFINAEですか)?
サンプルコードは次のとおりです。
Gcc 4.5は、これがコンパイラエラーであると述べており、clangはアサーション違反を吐き出します。
関心のあるいくつかの関連する質問があります:
FCD-C ++ 0xは、ここで何が起こるべきかを明確に指定していますか?
コンパイラはこのコードを拒否するのは間違っていますか?
演繹の「即時コンテキスト」をもう少し適切に定義する必要がありますか?
ありがとう!
c++ - 部分的なテンプレートの特殊化: 特殊化されたテンプレート パラメーターのプロパティの照合
の通常のテンプレートになるが、特殊化になるA
ような部分的な特殊化を定義する方法はありますか?A<C, B<P1> >
A
A<C, B<P2> >
Marcelo に応じて編集: より具体的には、特殊化は B だけでなく、特定のプロパティを示す任意の型で選択する必要があります。たとえば、最初の引数が P2 であるテンプレートです。
目標は、 を使用して のようなものを記述できるようにするY
ための優れたインターフェイスを提供することです。A
A<C, Y<P2,Q> >
テンプレート パラメータをテンプレート テンプレート パラメータに置き換えるのはY
いいことですが、それに基づいて部分的に特殊化する方法はありP
ますか?
意図は次のようなものを書くことです:
In silico に応じて編集: テンプレート テンプレート パラメーターを作成するのはいいことだと言いましたが、実際には、論理的にリンクされたプロパティをグループ化するために使用することですが、1 つに基づいて専門Y
化するという、私がやりたかったことの目的を無効にします。それらのサブプロパティの。Y
A
特殊化に特性を追加してからtemplate <> class B<P2>
SFINAE を使用する方法はありA
ますか? 意図は次のようなものを書くことです:
c++ - boost::enable_ifクラステンプレートメソッド
私はこれを見るテンプレートメソッドを持つクラスを取得しました:
明らかに、両方のテンプレートがインスタンス化され、コンパイル時エラーが発生します。テンプレートメソッドのインスタンス化は、無料の関数のインスタンス化とは異なりますか?これを別の方法で修正しましたが、何が起きているのか知りたいです。私が考えることができる唯一のことは、この動作を引き起こす可能性があります。有効化条件は、即時のテンプレート引数ではなく、クラステンプレート引数に依存します。
ありがとうございました
c++ - sfinae は関数本体をインスタンス化しますか?
通常の SFINAE トリックを使用して、クラスの特定のメンバー関数の存在を検出したいと考えています。
void* allocate(std::size_t)
これは、非標準のメンバ関数 (おそらく生メモリ アロケータ)を持つ別の種類のアロケータを検出することに注意してください。
次に、不完全な型と、その不完全な型の std::allocator があります。
そして、test_alloc が探しているものかどうかを確認しています。
などstruct test
を「使う」時、きっと完成するtest_alloc
別のコンパイル単位で。ただし、has_alloc テストが発生すると、コンパイラは std::allocator の割り当て関数をインスタンス化しようとし、不完全な型の sizeof が関数本体内で使用されていることを検出し、ハード エラーを引き起こします。などのように使用する際にアロケートの実装を分けて別々にインクルードすればエラーは発生しないようです
そしてtest_def.hpp
含む
しかし、私はこれを行うことができますが、実装を分離することはできませんalloc<T>
. std::allocator
私が探しているのは、 の関数が にvoid* allocate(size_t)
存在するかどうかをテストできることtest_alloc
です。そうでない場合は否定的にテストされ、はいの場合、つまり関数シグネチャが一致する場合、そこでインスタンス化できなくても、肯定的にテストされます。
c++ - 構造部分の特殊化でSFINAEを使用してファンクターをキャッチする
いくつかの複雑な理由で、サポートされているタイプT(テンプレートから取得)を選択したタイプのリストに変換したいと思います。このために、「変換」という名前のテンプレート構造を使用してみました。例えば:
上記のものは、テンプレートの特殊化を使用して簡単に実装できます。しかし、問題を引き起こしている1つのケースがあります:
これを処理するには、SFINAEを使用する必要があると思いますが、コンパイルすることができません。
以下のコードは、「部分的な特殊化はプライマリテンプレートの引数リストと一致できません」(つまり、「変換」の記述は禁止されています)を示しています。
そして、これは私に「テンプレートパラメータが使用されていないか、部分的な特殊化で推論可能」(つまり、Tが使用されていないと考えている)を与えます:
どうすればよいかわかりません。すべての試行で、上記の2つのエラーのいずれかが発生します。
編集:同じモデルを使用して他の一般的なものをキャッチしたいので、特殊化されていない構造で「typedefTtype」とだけ書くことはできません。
ありがとう
c++ - SFINAE非メンバー関数の存在を検出する
非メンバーメソッドが定義されているかどうかに応じて、テンプレートを特殊化する方法を知っている人はいますか?メンバー関数が存在するかどうかを特殊化する方法はたくさんあることは知っていますが、非メンバーの例を見たことがありません。特定の問題は、shared_ptrのoperator <<を特殊化して、operator<<がTに定義されている場合はoperator<<を適用し、それ以外の場合は単なるポインター位置を出力することです。すべてのクラスがoperator<<をメンバーとして定義していれば素晴らしいのですが、残念ながら多くのクラスが無料の関数を使用しています。私は次のようなものを想像しています:
編集:後世のために、ここに実用的な解決策がありました。boost :: shared_ptrには、アドレスを出力するデフォルトの演算子<<がすでにあるため、disable_ifは不要であることに注意してください。operator <<は参照を返すため、これは機能します。一般的なケースでは、問題の関数の戻り値のタイプを反映するようにこれを調整する必要があると思います。
c++ - 非 C++ プログラマーに C++ SFINAE を説明する
C++ の SFINAE とは?
C++に詳しくないプログラマーにもわかりやすい言葉で説明していただけませんか?また、SFINAE は Python のような言語のどの概念に対応していますか?
c++ - SFINAE: いくつかの失敗は他よりも平等ですか?
「名前」というメンバーを持つクラスを区別するためにSFINAEを使用しようとしています。標準パターンと思われるものを設定しましたが、機能していません。「失敗した」置換を黙って無視する代わりに、コンパイラはエラーを生成します。
私はいくつかのテンプレート置換ルールに遭遇したと確信しています。誰かがどれを説明できるかを教えていただければ幸いです。
これは簡略化された例です。私はgccを使用しています: