C++ Templates metaprogramming 第二章练习 2-0. 的三种解法 // test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <boost/tr1/type_traits.hpp> #include <boost/static_assert.hpp> #include <boost/mpl/if.hpp> //struct result<class T> //{ // static const bool value=boost::is_reference<T>; //} namespace test1{ template<class T, bool isRef = std::tr1::is_reference<T>::value > struct add_const_ref{ typedef T const & type; }; template <class T> struct add_const_ref<T, true>{ typedef T type; }; } namespace test2 { template <class T, bool isRef> struct add_const_ref_helper { typedef T const& type; }; template <class T> struct add_const_ref_helper<T, true> { typedef T type; }; template <class T> struct add_const_ref { typedef typename add_const_ref_helper<T, std::tr1::is_reference<T>::value>::type type; //像调用函数一样使用辅助模板类 }; } namespace test3 { template <bool isRef> struct add_const_ref_helper //外覆类 { template <class T> struct work { typedef T const & type; }; }; template <> struct add_const_ref_helper<true> { template <class T> struct work { typedef T type; }; }; template <class T> struct add_const_ref { typedef typename add_const_ref_helper<std::tr1::is_reference<T>::value>::work<T>::type type; }; } namespace test4 //关于外覆类的另一个例子 { using boost::mpl::bool_; struct and_ { template <typename a, typename b> struct work : public bool_<a::value && b::value> { }; }; struct or_ { template <typename a, typename b> struct work : public bool_<a::value || b::value> { }; }; //要求实现的功能: //par1: bool_: true return par2 and_ par3 // false return par2 or_ par3 template <typename arg1> struct get_op { typedef boost::mpl::if_<arg1, and_, or_> type; // arg1 ? arg2 : arg3 //这里在没有使用外覆类的时候会因为模板类没有实例化而出错 //出错例见namespace test5 }; template <typename op, typename arg1, typename arg2> struct apply { typedef typename op::work<arg1, arg2>::type type; }; template <typename arg1, typename arg2, typename arg3> struct work { typedef typename apply<typename get_op<arg1>::type, arg2, arg3>::type type; }; } namespace test5 { using boost::mpl::bool_; template<typename a,typename b> struct and_ : public bool_<a::value && b::value> { }; template <typename a, typename b> struct or_ : public bool_<a::value || b::value> { }; //par1: bool_: true return par2 and_ par3 // false return par2 or_ par3 template <typename arg1> struct get_op { typedef boost::mpl::if_<arg1, and_, or_> type; // arg1 ? arg2 : arg3 //error C3203: “and_”: 未专用化的类 模板 不能用作 模板 变量,该变量属于 模板 参数“T2”,应为 real 类型 //因此在test4中建立普通类and_和or_,其中定义模板类 }; template <typename op, typename arg1, typename arg2> struct apply { typedef typename op<arg1, arg2>::type type; }; template <typename arg1, typename arg2, typename arg3> struct work { typedef typename apply<typename get_op<arg1>::type, arg2, arg3>::type type; }; } using namespace test3; //验证,如果is_same结果不为true,则编译时报错 BOOST_STATIC_ASSERT((std::tr1::is_same<typename add_const_ref<int &>::type, int&>::type::value)); BOOST_STATIC_ASSERT((std::tr1::is_same<typename add_const_ref<int const &>::type, int const &>::type::value)); BOOST_STATIC_ASSERT((std::tr1::is_same<typename add_const_ref<int>::type, int const &>::type::value)); int main() { }