2015-12-15 9 views
5

を構築することが可能です私はタイプがvector<...>であればリターンはvector<...>::size_typeになり、ない場合、それはintなり、タイプを決定するためにstd::conditionalを使用するとします。 (ほんの一例)。はlazy_conditionalメタ関数

std::conditionalを使用するには、素朴な方法:

template<class V> struct is_vector : std::false_type{}; 
template<class T> struct is_vector<std::vector<T>> : std::true_type{}; 

template<class C> 
using my_size_type = typename std::conditional< 
    not is_vector<C>::value, 
    int, 
    C::size_type // note that this line only makes sense when condition is false 
>::type; 

しかしこれが失敗Cdoubleを言うのであればあるため、double::size_typeはそれが第二falseオプションの評価であったとしても、エラーになります。

したがって、false(または第2のfalse)文が評価されないような種類のlazy_conditionalがあるかどうかは疑問です。

私はここに何かを見つけました:https://stackoverflow.com/a/5317659/225186しかし私は私の例を使用する方法を知らない。私はstd::conditionalを使用せずに同じ結果を取得する方法を知っている


注:何とか短絡するstd::conditionalをカプセル化lazy_conditionalがある場合

template<class V> struct my_size_type{typedef int type;}; 
template<class T> struct my_size_type<std::vector<T>>{typedef std::vector<T>::size_type type;}; 

質問です。私はhttps://stackoverflow.com/a/5317659/225186でアイデアを使用して、次のようこれに取得するために管理し、いくつかのトライアル・エラーの後


。また、C::size_typeは先験的な表現では全く出現しないので、std::lazy_conditionalを書くことはできないと考えるので、2段階式が必要です。

template<class C, bool B> struct false_case{ 
    typedef void type; 
}; 
template<class C> struct false_case<C, false>{ 
    typedef typename C::size_type type; 
}; 

template<class C> 
using size_type = typename std::conditional< 
    not is_vector<C>::value, 
    int, 
    typename false_case<C, not is_vector<C>::value>::type 
>::type; 

それぞれのケースが異なるため、これをマクロに凝縮さえできませんでした。

答えて

4

間接参照が必要です。

template<class T> struct identity { using type = T; }; 

template<class C> 
struct size_type_of : identity<typename C::size_type> { }; 

template<class C> 
using size_type = typename std::conditional<not is_vector<C>::value, 
              identity<int>, 
              size_type_of<C>>::type::type; 

ポイントは、あなたはそれが1を持って知っているまで(size_type_of<C>をインスタンス化することによって)C::size_typeを見て遅延させることです。

template<class C> 
using size_type_t = typename C::size_type; 

template<class C> 
using size_type_or_default = std::experimental::detected_or_t<int, size_type_t, C>; 
+0

[OK]を、私はそれのようにカプセル化することができないと思います。


あなたが本当にやりたいことは、「それ以外の場合は、存在する場合C::size_typeint」の場合は、その後、std::experimental::detected_or_tはあなたの友達です'lazy_conditional 'です。とにかく、これはまた、フリー関数がメンバ関数よりも優れていることを示しています(フリー関数がジェネリックコードのメンバ関数より優れているように、T :: size_typeに頼るのではなく、std :: size_type_of :: typeを持っています)。 – alfC

+0

ああ、これは私が何度も何度も発見したものです。最後に私がここでやったのと同じです:http://stackoverflow.com/questions/5839357/detect-operator-support-with-decltype-sfinae/18603716# 18603716 – alfC

+0

'detected_or_t'互換性について:http://stackoverflow.com/questions/36418570/what-c​​ompiler-option-library-do-i-need-to-use-detect-or-t-type-trait?noredirect= 1#comment60486585_36418570 – alfC

関連する問題