簡體   English   中英

范圍-v3中的CONCEPT_REQUIRES_實現

[英]CONCEPT_REQUIRES_ implementation in ranges-v3

試圖學習如何使用Eric Niebler的range-v3庫,並閱讀源代碼,我看到了宏定義:

#define CONCEPT_PP_CAT_(X, Y) X ## Y
#define CONCEPT_PP_CAT(X, Y)  CONCEPT_PP_CAT_(X, Y)

/// \addtogroup group-concepts                                                                                                                                                                  
/// @{                                                                                                                                                                                          
#define CONCEPT_REQUIRES_(...)                                                      \
    int CONCEPT_PP_CAT(_concept_requires_, __LINE__) = 42,                          \
    typename std::enable_if<                                                        \
        (CONCEPT_PP_CAT(_concept_requires_, __LINE__) == 43) || (__VA_ARGS__),      \
        int                                                                         \
    >::type = 0                                                                     \
    /**/

簡而言之,模板定義如下:

template<typename I, typename O,
    CONCEPT_REQUIRES_(InputIterator<I>() &&
                      WeaklyIncrementable<O>())>
void fun_signature() {}

翻譯為:

template<typename I, typename O,
         int a_unique_name = 42,
         typename std::enable_if
           <false || (InputIterator<I>() &&
                      WeaklyIncrementable<O>()), int>::type = 0
        >
void fun_signature() {}

我想知道為什么宏實現這種方式。 為什么需要這個整數,為什么它需要一個false || cond false || cond而不僅僅是cond模板參數?

像...這樣的模板定義被翻譯為......

關。 它實際上翻譯為:

template<typename I, typename O,
         int a_unique_name = 42,
         typename std::enable_if
           <a_unique_name == 43 || (InputIterator<I>() &&
                      WeaklyIncrementable<O>()), int>::type = 0
        >
void fun_signature() {}

唯一命名的int是為了確保enable_if的條件依賴於模板參數,以避免在模板定義時而不是在實例化時檢查條件,以便SFINAE可以發生。 考慮這個類定義:

template<class T>
struct S {
    template<class U, CONCEPT_REQUIRES_(ranges::Integral<T>())>
    void f(U);
};

沒有inject-unique- int ,這個定義會降低到:

template<class T>
struct S {
    template<class U, std::enable_if_t<ranges::Integral<T>()>>
    void f(U);
};

由於ranges::Integral<T>()不依賴於此函數模板的參數,編譯器將診斷出std::enable_if_t<ranges::Integral<T>()> - 它降低為typename std::enable_if<ranges::Integral<T>()>::type - std::enable_if<false>因為std::enable_if<false>包含任何名為type成員。 使用inject-unique- int ,類定義降低到:

template<class T>
struct S {
    template<class U, int some_unique_name = 42,
        std::enable_if_t<some_unique_name == 43 || ranges::Integral<T>()>>
    void f(U);
};

現在,編譯器無法在模板定義時對enable_if_t執行任何分析,因為some_unique_name是模板參數,可由用戶指定為43

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM