は、次のコードスニペットを考えてみてくださいクラステンプレートから派生しているかどうかをチェックしますc<F, B>
から?型特性は、いくつかのタイプが
例:F = e<D>
についてc<F, B>
由来するD
ようF
に応じて、いくつかのタイプB
あります。
は、次のコードスニペットを考えてみてくださいクラステンプレートから派生しているかどうかをチェックしますc<F, B>
から?型特性は、いくつかのタイプが
例:F = e<D>
についてc<F, B>
由来するD
ようF
に応じて、いくつかのタイプB
あります。
この回答は質問に焦点を当てています。タイプF
考える
は、どのように私はF
がc<F, B>
から派生しB
ように、いくつかの種類があるかどうかを確認することができますか?
そしてわかりやすくするためのコメント。
F
が何らかのB
ためc<F, B>
に由来する場合形質が確認する必要があります(それはB
が何であるかは重要ではありません)。
二constexpr
機能は、「誘致」と離れて他のタイプからベースc<F, B>
を区別するために使用することができます。 ファンクションテンプレートは、deduce types(これは、要件の一部を満たす必要があります(B
を満たす必要があるため)が優先されます。次のような形式のもの...
template <typename F, typename B>
constexpr bool check_base(C<F, B> &&) { return true; }
template <typename F>
constexpr bool check_base(...) { return false; }
次のサンプルでは、使用シナリオが改善され、基本的な動作が示されています。
#include <utility>
template <typename A, typename B>
struct C {};
template <typename F, typename B>
constexpr std::true_type check_base_(C<F, B>&&) { return {}; }
template <typename F>
constexpr std::false_type check_base_(...) { return {}; }
template <typename T>
using check_base = decltype(check_base_<T>(std::declval<T>()));
template <typename D>
struct E : C<E<D>, D> {};
struct FailF {};
int main()
{
static_assert(check_base<E<int>>());
static_assert(!check_base<FailF>());
}
constexpr
を削除した場合は、check_base_
関数の不要なインライン定義を削除することもできます。
注:溶液/にアクセス基底クラス(すなわちないprivate
又はprotected
)をアサート前提。基本クラスがprivate
の場合、上記のコードはアクセシビリティエラーでコンパイルに失敗します。以下のコードは失敗しません。SFINAEは、コンパイルを続行するために行われます。
Online demo here。 [テンプレートクラスのいくつかの専門は、特定のクラスの基底クラスであるかどうかを確認するために形質]
#include <utility>
#include <type_traits>
template <typename A, typename B>
struct C {};
template <typename F, typename B>
std::true_type check_base_(C<F, B>&&, typename std::enable_if<std::is_convertible<F, C<F,B>>::value>::type* = nullptr);
template <typename F>
std::false_type check_base_(...);
template <typename T>
using check_base = decltype(check_base_<T>(std::declval<T>()));
template <typename D>
struct Example : C<Example<D>, D> {};
struct CtorTest : C<CtorTest, int> { CtorTest(int, int) {} };
struct PrivateBase : private C<PrivateBase, double> {};
struct FailTest {};
int main()
{
static_assert(check_base<Example<int>>(), "fail...");
static_assert(check_base<CtorTest>::value, "fail...");
static_assert(!check_base<PrivateBase>(), "fail...");
static_assert(!check_base<FailTest>(), "fail...");
}
の可能な重複を(http://stackoverflow.com/questions/25845536/trait-to-check-if-some-specialization -f-template-class-is-base-of-specifi) – Orient
もし 'c'ならあなたが作者であれば、テンプレート以外の' class 'クラスから 'c'を派生させるとあなたの人生を楽にすることができますfoo {} 'を実行し、次に' f'が 'foo'から派生したものであるかどうかを' std :: is_base_of'を使って調べます。 –
@ JohannesSchaub-litbはい、私はそのようなe_tagクラスを使うことに決めました。 – 0xbadf00d