Skip to content

Specialization

本文主要给出template specializaiton的例子,关于实现,在Compile-template中进行了解释;

Primary template and template specialization

primary template和template specialization是两个相对的概念,关于两者之间的关系,在下面章节中进行了介绍:

路径 章节 观点
Compile-template Partial template specialization是primary template的附庸 Partial template specialization是primary template的附庸
C++\Guide\Polymorphism Overload、specialization、subclass都是对某种“特殊情况的说明”(即**最最特殊的实现**)

cppreference explicit (full) template specialization

Examples

is_void

#include <iostream>
template<typename T>   // primary template
struct is_void: std::false_type
{
};
template<>  // explicit specialization for T = void
struct is_void<void> : std::true_type
{
};
int main()
{
    // for any type T other than void, the
    // class is derived from false_type
    std::cout << is_void<char>::value << '\n';
    // but when T is void, the class is derived
    // from true_type
    std::cout << is_void<void>::value << '\n';
}

cppreference partial template specialization

Examples

理解下面这些example的前提是理解compiler compile template specialization的流程,参见 Compile-template 章节。

is_pointer: specialization of pointer type

accu An introduction to C++ Traits

#include <iostream>

template<typename T>
struct is_pointer
{
    static const bool value = false;
};

template<typename T>
struct is_pointer<T*>
{
    static const bool value = true;
};

int main()
{
    // for any type T other than void, the
    // class is derived from false_type
    std::cout << is_pointer<char>::value << '\n';
    // but when T is void, the class is derived
    // from true_type
    std::cout << is_pointer<void*>::value << '\n';
}

remove_reference: specialization of reference type

  // Reference transformations.

  /// remove_reference
  template<typename _Tp>
    struct remove_reference
    { typedef _Tp   type; };

  template<typename _Tp>
    struct remove_reference<_Tp&>
    { typedef _Tp   type; };

  template<typename _Tp>
    struct remove_reference<_Tp&&>
    { typedef _Tp   type; };

std::make_unique: specialization of array type

gcc/libstdc++-v3/include/bits/unique_ptr.h

#if __cplusplus >= 201402L
  /// @relates unique_ptr @{
#define __cpp_lib_make_unique 201304

  /// @cond undocumented

  template<typename _Tp>
    struct _MakeUniq
    { typedef unique_ptr<_Tp> __single_object; };

  template<typename _Tp>
    struct _MakeUniq<_Tp[]>
    { typedef unique_ptr<_Tp[]> __array; };

  template<typename _Tp, size_t _Bound>
    struct _MakeUniq<_Tp[_Bound]>
    { struct __invalid_type { }; };

  /// @endcond

  /// std::make_unique for single objects
  template<typename _Tp, typename... _Args>
    inline typename _MakeUniq<_Tp>::__single_object
    make_unique(_Args&&... __args)
    { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }

  /// std::make_unique for arrays of unknown bound
  template<typename _Tp>
    inline typename _MakeUniq<_Tp>::__array
    make_unique(size_t __num)
    { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }

  /// Disable std::make_unique for arrays of known bound
  template<typename _Tp, typename... _Args>
    inline typename _MakeUniq<_Tp>::__invalid_type
    make_unique(_Args&&...) = delete;
  // @} relates unique_ptr
#endif // C++14

std::unique_ptr: specialization of array type

gcc/libstdc++-v3/include/bits/unique_ptr.h

/// 20.7.1.2 unique_ptr for single objects.
template<typename _Tp, typename _Dp = default_delete<_Tp>>
class unique_ptr
{
};

/// 20.7.1.3 unique_ptr for array objects with a runtime length
// [unique.ptr.runtime]
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 740 - omit specialization for array objects with a compile time length
template<typename _Tp, typename _Dp>
class unique_ptr<_Tp[], _Dp>
{

};

Specialization on constant

这是一种比较特殊的template specialization ,将它归入到了Dispatch-based-on-constant章节。

fluentcpp Template Partial Specialization In C++

stackoverflow Understanding (simple?) C++ Partial Template Specialization

Example

1、trait

2、Mazrog/srlzio

其中对partial template specialization的运用非常值得借鉴