template metaprogramming
c++11
template specialization
partial specialization
這裡嘗試從 C++11 規格來學習 Template metaprogramming。(Template metaprogramming 並不是只能在 C++ 中實現)
C++11, 21.2 Character traits 提到了一個 struct template
和 4 個相關的 explicit specializations
,char_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>
{
...
};
參考上面 gcc
在 char_traits
的實作,寫一小段 code 體會一下 explicit specializations
。
第 8、14 行的 char_traits<char>
和 char_traits<wchar_t>
就是 char_traits
的 explicit 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
從 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*)
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