std::enable_if 学习

std::enable_if

标准库文档这样写到:

辅助类型

template< bool B, class T = void >
using enable_if_t = typename enable_if::type;

  (C++14 起)
     

可能的实现

template
struct enable_if {};
 
template
struct enable_if { typedef T type; };

这个东西标准文档里写的很清楚,看代码也能看明白,但是,在标准文档里面的注释,属实把我整蒙了。

 

注解

常见错误是声明二个函数模板,而它们仅于其默认模板实参相异。这是无效的,因为这些函数声明被当做同一函数模板的再声明(默认模板实参不为函数模板等价所考虑)。

 

可能翻译的不太好,我又查了英文版同样的内容

 

Notes

A common mistake is to declare two function templates that differ only in their default template arguments. This does not work because the declarations are treated as redeclarations of the same function template (default template arguments are not accounted for in function template equivalence).

 

又用翻译软件翻译了一下:

一个常见的错误是声明两个函数模板,这两个模板的不同之处仅在于它们的默认模板参数。这不起作用,因为声明被视为同一函数模板的重新声明(在函数模板等价中不考虑默认模板参数)。

 

而且还贴心的给出了例子:

struct T {

enum { int_t, float_t } m_type;

template >

>

T(Integer) : m_type(int_t) {}



template >

>

T(Floating) : m_type(float_t) {} // 错误:不能重载

};

 

 

就是说两个函数模板,就算是默认模板参数不同,编译器也不会展开他们,会把他们算作同一模板,这个注释其实和enable_if没有关,但确常用enable_if来做默认模板参数。

简化一下问题,比如,以下的struct T 也编译不过

struct T {

enum { int_t, float_t } m_type;

template 

T(Integer) : m_type(int_t) {}



template 

T(Floating) : m_type(float_t) {} // 错误:不能重载

};

 

 

难怪只看一些默认模板参数是typename T=void

 

然后例子还给出了能够正确编译的方法

struct T {

enum { int_t, float_t } m_type;

template ::value, int> = 0

>

T(Integer) : m_type(int_t) {}



template ::value, int> = 0

>

T(Floating) : m_type(float_t) {} // OK

};

 

到现在还没讲这个例子的意思是,例子想要根据T的构造函数传入的类型,来初始化m_type的值,

如果类型是int型,m_type=0,如果是浮点型,m_type=1。

 

然后这里就很明确了std::enable_if_t::value, int> = 0 只是为了做SFINAE。

std::enable_if_t的模板类型可以很随意

 

比如如下的也可以编译通过

struct T {

enum { int_t, float_t } m_type;

template ::value, char*> = 0

>

T(Integer) : m_type(int_t) {}



template ::value, short> = 0

>

T(Floating) : m_type(float_t) {} // OK

};


 

 

但是唯独如下的形式编译不通过

struct T {

enum { int_t, float_t } m_type;

template ::value, double> = 0 //换成double,0或0.0f都不行

>

T(Integer) : m_type(int_t) {}



template ::value, double> = 0.0f //

>

T(Floating) : m_type(float_t) {} // OK

};

 

 

先留下一个疑问,如果有谁知道希望可以告诉我。

 

你可能感兴趣的:(std::enable_if 学习)