2017-01-06 8 views
3

私は異なるビュータイプを持っています。タイプはそれぞれstd::size_t View::dimensionメンバー定数とtypename View::value_typeメンバータイプです。 FromTo両方は、ビュー(is_view<>を使用して検証)であり、Fromの含有量はToに割り当てることができる場合SFINAE std :: enable_if引数

以下コンパイル型チェックが確認しなければなりません。 (同じ次元と変換可能な値の型)。

template<typename From, typename To> 
struct is_compatible_view : std::integral_constant<bool, 
    is_view<From>::value && 
    is_view<To>::value && 
    From::dimension == To::dimension && 
    std::is_convertible<typename From::value_type, typename To::value_type>::value 
> { }; 

is_view<T>それは常に、あらゆるタイプTため、std::true_typeまたはstd::false_typeに評価するようなものです。問題は、FromまたはToがビュータイプでない場合、From::dimension(たとえば)が存在しない可能性があり、is_compatible_view<From, To>がコンパイルエラーを引き起こすことです。 この場合、代わりにstd::false_typeと評価する必要があります。

is_compatible_viewは、SFINAEでstd::enable_ifと使用され、メンバ関数を無効にします。たとえば、ビュークラスは、メンバ関数を持つことができます

struct View { 
    constexpr static std::size_t dimension = ... 
    using value_type = ... 

    template<typename Other_view> 
    std::enable_if_t<is_compatible_view<Other_view, View>> assign_from(const Other_view&); 

    void assign_from(const Not_a_view&); 
}; 

Not_a_viewは、ビューではなく、is_compatible_view<Not_a_view, ...>でコンパイルエラーが発生します。 view.assign_from(Not_a_view())を呼び出すと、SFINAEは適用されず、コンパイラが最初のassign_from関数を解決しようとすると、コンパイルエラーが発生します。

is_compatible_viewは正しく動作するように書かれていますか? C++ではstd::conjunction<...>がこれを許可しますか?

答えて

4

タイプ特性の他の部分が既に真であることが確認されるまで、std::conditionalのようなものを使用して、タイプ特性の一部の評価を遅らせる方法があります。

です:私はconditional_t::typeの両方を使用してい

// this one is only valid if From and To are views 
template <class From, class To> 
struct is_compatible_view_details : std::integral_constant<bool, 
    From::dimension == To::dimension && 
    std::is_convertible<typename From::value_type, typename To::value_type>::value 
> { };   

// this is the top level one 
template<typename From, typename To> 
struct is_compatible_view : std::conditional_t< 
    is_view<From>::value && is_view<To>::value, 
    is_compatible_view_details<From, To>, 
    std::false_type>::type 
{ }; 

注意。 is_compatible_view_detailsは、FromToの両方が表示されている場合にのみインスタンス化されます。同様のアプローチは、上記とstd::conjunctionを使用することです


、同様に評価を遅らせますので、短絡のどの:

template <class From, class To> 
struct is_compatible_view : std::conjunction_t< 
    is_view<From>, 
    is_view<To>, 
    is_compatible_view_details<From, To> 
    > 
{ }; 

にどちらの方法を、あなたは詳細を引き出す必要があります。


第三のアプローチは、専門としてenable_if_tを使用することです:

ここ
template <class From, class To, class = void> 
struct is_compatible_view : std::false_type { }; 

template <class From, class To> 
struct is_compatible_view<From, To, std::enable_if_t< 
    is_view<From>::value && 
    is_view<To>::value && 
    From::dimension == To::dimension && 
    std::is_convertible<typename From::value_type, typename To::value_type>::value>> 
: std::true_type { }; 

enable_if_tの式のいずれかが悪い形成されている場合、SFINAEがで蹴り、私たちは主を使用しますテンプレート、false_typeです。

+0

私は実際にあなたの最初のスニペットに ':: type'のポイントを実際には見ません。また、ユースケースによっては、 'From :: value_type'などのエラーを直後のコンテキストにプルする' enable_if_compatible_view'エイリアステンプレートを作成すれば十分でしょう。 –

関連する問題