[英]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.