简体   繁体   English

范围-v3中的CONCEPT_REQUIRES_实现

[英]CONCEPT_REQUIRES_ implementation in ranges-v3

Trying to learn how to use Eric Niebler's ranges-v3 library, and reading the source code, I saw that macro definition: 试图学习如何使用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                                                                     \
    /**/

So, in short, a template definition like: 简而言之,模板定义如下:

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

is translated as: 翻译为:

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() {}

I would like to know why is that macro implement that way. 我想知道为什么宏实现这种方式。 Why is that integer needed, and why does it need a false || cond 为什么需要这个整数,为什么它需要一个false || cond false || cond and not just a cond template argument? false || cond而不仅仅是cond模板参数?

a template definition like ... is translated as ... 像...这样的模板定义被翻译为......

Close. 关。 It actually translates as: 它实际上翻译为:

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() {}

The uniquely named int is there in order to ensure that the condition for enable_if is dependent on a template parameter, to avoid the condition being checked at template definition time instead of at instantiation time so that SFINAE can happen. 唯一命名的int是为了确保enable_if的条件依赖于模板参数,以避免在模板定义时而不是在实例化时检查条件,以便SFINAE可以发生。 Consider this class definition: 考虑这个类定义:

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

without the injected-unique- int , this definition would lower to: 没有inject-unique- int ,这个定义会降低到:

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

and since ranges::Integral<T>() isn't dependent on a parameter of this function template, compilers will diagnose that std::enable_if_t<ranges::Integral<T>()> - which lowers to typename std::enable_if<ranges::Integral<T>()>::type - is ill-formed because std::enable_if<false> contains no member named type . 由于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成员。 With the injected-unique- int , the class definition lowers to: 使用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);
};

now a compiler cannot perform any analysis of the enable_if_t at template definition time, since some_unique_name is a template parameter that might be specified as 43 by a user. 现在,编译器无法在模板定义时对enable_if_t执行任何分析,因为some_unique_name是模板参数,可由用户指定为43

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM