Skip to content

关于本章

SFINAE是实现对**static polymorphism**的过程进行控制的基础

NOTE:

1、这是custom polymorphism

2、C++的static polymorphism主要有两种:

a、overload

b、specialization

programmer可以使用SFINAE实现对上述两种static polymorphism的控制,cppreference sfinae 就是按照这种思路来进行编写的

在cppreference Templates中有如下介绍:

When a class template specialization is referenced in context that requires a complete object type, or when a function template specialization is referenced in context that requires a function definition to exist, the template is instantiated (the code for it is actually compiled), unless the template was already explicitly specialized or explicitly instantiated. Instantiation of a class template doesn't instantiate any of its member functions unless they are also used. At link time, identical instantiations generated by different translation units are merged.

简而言之,template是只有在使用的情况下才会被“instantiation”,SFINAE**控制了对**template specialization(concrete/implementation)的**选择**,实现了

一、conditional compiling,此处的又可以称为: compile-time dispatch

二、对**static polymorphism**的过程进行控制

C++支持template function、template class,它们都可以通过SFINA来进行控制:

1 Controlling overload resolution: function overloads

NOTE: 参见:https://foonathan.net/2015/11/overload-resolution-4/

2 Controlling class template specializations

SFINAE-based custom polymorphism的前提是有substitution

SFINAE的condition

C++支持非常灵活的SFINAE的condition,下面是对这些condition的一个简单分类:

1) Type-based condition

基于type requirement/concept进行dispatch,type requirement/concept是generic programming中的概念,参见 Theory\Programming-paradigm\Generic-programming章节。

2) Non-type-based condition

之前写过一个应用: 根据消息类型来进行dispatch,消息类型是enum,是integer,不是type,无法按照type来进行dispatch,只能使用constexpr function + std::enable_if来表达condition(AMUSTAPI是一个非常好的例子),这种做法超过type的限制,允许programmer灵活地进行dispatch。

SFINAE+trait+enable_if

SFINAE、trait、enable_if,三者是实现template metaprogramming的基础,实现上,往往是三者一起使用才能够发挥出c++的强大之处。

对三者总结的最好的文章是:boost enable_if,它讲到了精髓,下面是cppreference中对三者的总结:

cppreference SFINAE#Library support段中关于enable_if和SFINAE的总结,原文描述如下:

The standard library component std::enable_if allows for creating a substitution failure in order to enable or disable particular overloads based on a condition evaluated at compile time.

cppreference std::enable_if段中关于SFINAE、trait的总结,原文描述如下:

This metafunction is a convenient way to leverage SFINAE to conditionally remove functions from overload resolution based on type traits and to provide separate function overloads and specializations for different type traits.

cppreference SFINAE#Library support段中关于trait和SFINAE的总结,原文描述如下:

In addition, many type traits are implemented using SFINAE.

void_t and SFINAE

cppreference SFINAE#Library support段中的总结如下:

The standard library component std::void_t is another utility metafunction that simplifies SFINAE applications.

TO READ

Template SFINAE & type-traits

How to Make SFINAE Pretty – Part 2: the Hidden Beauty of SFINAE