Try   HackMD

Template metaprogramming 學習筆記

tags: template metaprogramming c++11 template specialization partial specialization

Introduction

這裡嘗試從 C++11 規格來學習 Template metaprogramming。(Template metaprogramming 並不是只能在 C++ 中實現)

struct template

C++11, 21.2 Character traits 提到了一個 struct template 和 4 個相關的 explicit specializationschar_traits<char>char_traits<char16_t>char_traits<char32_t>char_traits<wchar_t>。先看一段 gcc 的 code 來感受一下 struct template 和 explicit specialization。

libstdc++-v3, char_traits.h, line 283

template<class _CharT>
    struct char_traits : public __gnu_cxx::char_traits<_CharT>
    { };

libstdc++-v3, char_traits.h, line 288

/// 21.1.3.1  char_traits specializations
  template<>
    struct char_traits<char>
    {
    ...
    };

實驗

參考上面 gccchar_traits 的實作,寫一小段 code 體會一下 explicit specializations
第 8、14 行的 char_traits<char>char_traits<wchar_t> 就是 char_traitsexplicit specializations

#include <iostream> template<class _CharT> struct char_traits : public __gnu_cxx::char_traits<_CharT> { }; template<> struct char_traits<char> { typedef char char_type; }; template<> struct char_traits<wchar_t> { typedef wchar_t char_type; }; int main(){ return 0; }
$ gcc template.cpp -lstdc++ -o template

Template function

  • Function templates
  • Template argument deduction
  • Type deduction
  • Overload Resolution

從 C++11 (20.8.11.2 Class template function) 看一下 template function 怎麼寫。

template<class> class function; // undefined
template<class R, class... ArgTypes>
class function<R(ArgTypes...)> {
   ...
};

C++11 (14.5.6 Function templates)function template 的定義是這樣

A function template defines an unbounded set of related functions.

C++11 (14.5.6.2/4 Partial ordering of function templates) 有一些範例

template<class T> void f(T);
template<class T> void f(T*);
template<class T> void f(const T*);

實驗

參考上述 C++11 規格寫一段 code 來感受一下 function template。

#include <iostream> using namespace std; template<class T> void f(T){ std::cout << "f(T)" << std::endl; }; template<class T> void f(T*){ std::cout << "f(T*)" << std::endl; }; template<class T> void f(const T*){ std::cout << "f(const T*)" << std::endl; }; int main(){ const double *p; f(p); return 0; }

第 18 行 f(p);,如 C++11 (14.5.6.2/4 Partial ordering of function templates) 所說

f(const T*) is more specialized than f(T) or f(T*)

所以 output 會是 f(const T*)

$ gcc template-func.cpp -lstdc++ -o template-func
$ ./template-func 
f(const T*)

Template specialization

  • C++11 對 Template specialization 的定義
  • partial specialization

C++11 規格, 14.5.5.3 對 Template specialization 的定義是這樣

A class template specialization is a distinct template. The members of the class template partial specialization are unrelated to the members of the primary template.

舉例說明 template specialization 和 partial specialization

template<class T, int I> struct A { void f(); }; template<class T, int I> void A<T, I>::f() { }; template<class T> struct A<T, 2> { void f(); }; int main() { A<char, 2> a2; a2.f(); // 不會呼叫 template<class T, int I> void A<T, I>::f() { }; return 0; }

A<T, I>::f()A<T, 2>::f()unrelated,所以 A<char, 2> 是未定義的。因此,link 的時候會出現以下的 error:(link-time 就可以發現這個 error,不用等到 run-time)

$ gcc -std=c++11 test.cpp -o test
/tmp/ccw9gLnA.o: 於函式 main:
test.cpp:(.text+0x1f): 未定義參考到 A<char, 2>::f()
collect2: error: ld returned 1 exit status

Reference