简体   繁体   English

具有类默认值的模板参数

[英]template parameter with default value for class

I dont quite understand below code, there are two parameters for the template, the second one has class = xxxx , This seems strange to me. 我对下面的代码不太了解,模板有两个参数,第二个参数具有class = xxxx ,这对我来说似乎很奇怪。 Can you explain it to me how should I understand it? 您能给我解释一下我该怎么理解吗? and besides std::enable_if , is there any other use case for this c++ feature ? 除了std::enable_if之外,此c ++ 功能还有其他用例吗?

template < class T,
class = typename std::enable_if<std::is_integral<T>::value>::type>
bool is_even (T i) {return !bool(i%2);}

One word: SFINAE. 一个词:SFINAE。

Substitution Failure Is Not An Error. 替换失败不是错误。

Look for that word with google and a whole new world will open up for you. 用google寻找这个词,一个全新的世界将为您打开。

Let see the meaning of your code. 让我们看看代码的含义。

std::is_integral<typename T>::value

It's a boolean value, dependant from type T , with value true if T is a integral type, false otherwise. 这是一个布尔值,取决于类型T ,如果T是整数类型,则值为true ,否则为false

std::enable_if<bool B, typename T = void>::type

It's the type T , when B == true , nothing otherwise. 它是T类型,当B == true ,没有其他情况。

So, in your code 因此,在您的代码中

template < class T,
class = typename std::enable_if<std::is_integral<T>::value>::type>

when T is a integral type, the second (unnamed) template argument is substituted with a type (the default: void ; but, in this case, the exact type is irrelevant) and the function is activated. T是整数类型时,第二个(未命名)模板参数将用类型(默认值: void ;但是,在这种情况下,确切的类型无关紧要)替换,并激活该函数。 On the contrary, when T isn't a integral type, there is the failure in the substitution of the second template argument and this version of the is_even() function isn't activated (for type T ) and, this is the important point, it isn't an error (another version of is_even() can be activated). 相反,当T不是整数类型时,第二个模板参数的替换将失败,并且此版本的is_even()函数未激活(对于T类型),这是重要的一点,这不是错误(可以激活is_even()另一个版本)。

More interesting can be see how to implement an alternative version of is_even() , for non integral types. 更有趣的是可以看到如何为非整数类型实现is_even()的替代版本。 You can think that you can implement another version that negate std::is_integral 您可以认为可以实现另一个否定std::is_integral版本

template < class T,
class = typename std::enable_if<false == std::is_integral<T>::value>::type>

but this don't work (is an error and don't compile) because you have two is_even() templated function that differs (from the templates arguments point of view) only for a default argument. 但这是行不通的(是错误并且无法编译),因为您有两个is_even()模板化函数,它们仅针对默认参数而有所不同(从模板参数的角度来看)。

A solution can apply SFINAE to the return value 解决方案可以将SFINAE应用于返回值

#include <type_traits>
#include <iostream>

template <typename T>
typename std::enable_if<true == std::is_integral<T>::value, bool>::type
is_even (T const & i)
 { return ! (i%2); }

template <typename T>
typename std::enable_if<false == std::is_integral<T>::value, bool>::type
is_even (T const &)
 { return false; }


int main()
 {
   std::cout << "-- is 7 even ?     " << is_even(7) << '\n';
   std::cout << "-- is 8UL even ?   " << is_even(8LL) << '\n';
   std::cout << "-- is \"abc\" even ? " << is_even("abc") << '\n';

   return 0;
 }

In this way you have a version of is_even() enabled for integral type and a second version (that return even false ) for non integral types. 这样,您就为整数类型启用了is_even()版本, is_even()整数类型启用了第二个版本(甚至返回false )。

ps: sorry for my bad english. ps:对不起,我的英语不好。

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

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