quote的作用是把一个metafunction,变换成为一个metafunction class,我们都知道,metafunction是无法进行传递的。例如我们有一个metafunciton AddPointerMetaFunction作用是添加指针
template struct AddPotionerMetaFunction { typedef T* type; };
我们还有一个metafunction DoubleTime的一个参数是另外一个metafunction,并把它执行两次如:
template struct DoubleTime { typedef typename T ::type inner; typedef typename T ::type type; };
但是我们没有办法把一个metafunction传递给另外一个metafunction,因为metafunction必须要指定参数,这是已经实化了
如一下代码是错误的
DoubleTime<AddPointerMetaFunction<int>, int>::type;
而正确的办法是
struct AddPointerMetaFunctionClass { template struct apply { typedef typename AddPoinerMetaFunction ::type type; }; }; template struct DoubleTime { typedef typename T::apply ::type inner; typedef typename T::apply ::type type; }; DoubleTime ::type; //type is int**
我们可以看出metafunction class的必要性,而quote就是把metafunction变成metafunction class,因此上面的代码的效果等同于
如下面的代码
DoubleTime<boost::mpl::quote1<AddPointerMetaFunction>, int>::type; //type is int**
其中quote1指AddPointerMetaFunction只有一个输入参数。quoten表示输入的metafunction有n个参数
了解了quote的作用后我们来看看具体怎么样实现的
如果按照前文的编译器,我们可以从
boost/mpl/aux_/preprocessed/plain/quote.hpp line14~41
中找到相应的quote的源代码。我们仅仅通过阅读quote1的实现,可以得到quoten的实现方法
template< typename T, bool has_type_ > struct quote_impl : T { }; template< typename T > struct quote_impl< T,false > { typedef T type; }; template< template< typename P1 > class F // 值得注意的声明方式,代表了一个metafunction , typename Tag = void_ > struct quote1 { template< typename U1 > struct apply : quote_impl< F , aux::has_type< F >::value > { }; };其中注意看上面代码中注释那行,这个是唯一巧妙的地方