Template Argumentの個数と順番を任意にする
- boost::spirit::ruleで使われている
- Named Template Argumentsのように名前を書かなくてもよい
[]// pst_20050314.cpp : コンソール アプリケーションのエントリ ポイントを定義します。[]
[]//[][]#include[][] "stdafx.h"[]
[]#include[][] <iostream>[]
[]#include[][] <boost/mpl/vector.hpp>[]
[]#include[][] <boost/mpl/placeholders.hpp>[]
[]#include[][] <boost/type_traits.hpp>[]
[]#include[][] <boost/mpl/find_if.hpp>[]
[]#include[][] <boost/mpl/eval_if.hpp>[]
[]#include[][] <boost/mpl/identity.hpp>[]
[]#include[][] <boost/mpl/end.hpp>[][]// See: boost/spirit/core/non_terminal/impl/rule.ipp[]
[]namespace[] []pst_2005_03_14[] {
[]namespace[] []bst[] = ::[]boost[];
[]namespace[] []mpl[] = ::[]boost[]::[]mpl[];
[]using[] []mpl[]::[]_1[];[]// tag bases[]
[]struct[] []door_base[] { };
[]struct[] []wall_base[] { };
[]struct[] []room_base[] { };[]// helper[]
[]template[]< []typename[] []Base[], []typename[] []Default[],
[]typename[] []T0[], []typename[] []T1[], []typename[] []T2[] >
[]struct[] []get_param[] {
[]private[]:
[]typedef[] []mpl[]::[]vector[]<[]T0[],[]T1[],[]T2[]> []arguments[];
[]typedef[] []typename[] []mpl[]::[]find_if[]< []arguments[], []bst[]::[]is_base_and_derived[]<[]Base[], []_1[]> >::[]type[] []result_iter[];
[]public[]:
[]typedef[] []typename[] []mpl[]::[]eval_if[]<
[]bst[]::[]is_same[]<[]result_iter[], []typename[] []mpl[]::[]end[]<[]arguments[]>::[]type[]>,
[]mpl[]::[]identity[]<[]Default[]>, []mpl[]::[]deref[]<[]result_iter[]> >::[]type[] []type[];
};[]// defaults[]
[]struct[] []default_door[] : []door_base[] { []/*...*/[] };
[]struct[] []default_wall[] : []wall_base[] { []/*...*/[] };
[]struct[] []default_room[] : []room_base[] { []/*...*/[] };[]// MyHome[]
[]template[]< []typename[] []T0[] = []mpl[]::[]void_[], []typename[] []T1[] = []mpl[]::[]void_[], []typename[] []T2[] = []mpl[]::[]void_[] >
[]class[] []MyHome[] {
[]private[]:
[]typedef[] []typename[] []get_param[]<[]door_base[], []default_door[], []T0[], []T1[], []T2[]>::[]type[] []door_type[];
[]typedef[] []typename[] []get_param[]<[]wall_base[], []default_wall[], []T0[], []T1[], []T2[]>::[]type[] []wall_type[];
[]typedef[] []typename[] []get_param[]<[]room_base[], []default_room[], []T0[], []T1[], []T2[]>::[]type[] []room_type[];
[]public[]:
[]/*...*/[]
[]void[] []print[]() {
[]using[] []namespace[] []std[];
[]wcout[] << []L[][]"door_type is "[] << []typeid[]([]door_type[]).[]name[]() << []endl[];
[]wcout[] << []L[][]"wall_type is "[] << []typeid[]([]wall_type[]).[]name[]() << []endl[];
[]wcout[] << []L[][]"room_type is "[] << []typeid[]([]room_type[]).[]name[]() << []endl[] << []endl[];
}
};[]struct[] []cheap_door[] : []door_base[] { []/*...*/[] };
[]struct[] []expensive_door[] : []door_base[] { []/*...*/[] };
[]struct[] []woody_wall[] : []wall_base[] { []/*...*/[] };
[]struct[] []stony_wall[] : []wall_base[] { []/*...*/[] };
[]struct[] []threeDK_room[] : []room_base[] { []/*...*/[] };
[]struct[] []twoDK_room[] : []room_base[] { []/*...*/[] };
[]struct[] []suites[] : []expensive_door[], []stony_wall[], []threeDK_room[] { []/*...*/[] };[]void[] []test[]() {
[]MyHome[]<>().[]print[]();
[]MyHome[]<[]cheap_door[]>().[]print[]();
[]MyHome[]<[]twoDK_room[],[]expensive_door[]>().[]print[]();
[]MyHome[]<[]stony_wall[],[]twoDK_room[]>().[]print[]();
[]MyHome[]<[]threeDK_room[],[]expensive_door[],[]stony_wall[]>().[]print[]();
[]MyHome[]<[]suites[]>().[]print[]();
}
}[]int[] []_tmain[]([]int[] []argc[], []_TCHAR[]* []argv[][])
{
[]pst_2005_03_14[]::[]test[]();
[]std[]::[]wcin[].[]ignore[]();
[]return[] 0;
}