zoukankan      html  css  js  c++  java
  • 一道模板元编程题源码解答(replace_type)

    今天有一同学在群上聊到一个比较好玩的题目(本人看书不多,后面才知是《C++模板元编程》第二章里面的一道习题), 我也抱着试一试的态度去完成它, 这道题也体现了c++模板元编程的基础和精髓: 类型就是数据。

    题目如下所述:

    Write a ternary metafunction replace_type<c,x,y> that takes an arbitrary compound type c as its first parameter, and replaces all occurrences of a type x within c with y:

        typedef replace_type< void*, void, int >::type t1; // int*
        typedef replace_type<
            int const*[10]
          , int const
          , long
        >::type t2; // long* [10]
    
        typedef replace_type<
            char& (*)(char&)
          , char&
          , long&
        >::type t3; // long& (*)(long&)

    下面第一部分是我的实现, 第二部分是测试代码:

    1. 实现

    namespace xusd{
    
    template <typename C, typename X, typename Y>
    struct replace_type;
    
    template <typename X, typename Y>
    struct replace_type<X, X, Y>{
        typedef Y type;
    };
    
    template <typename C, typename X, typename Y>
    struct replace_type_impl{
        typedef C type;
    };
    
    template <typename C, typename X, typename Y>
    struct replace_type:public replace_type_impl<C, X, Y>{ };
    
    template <typename C, typename X, typename Y>
    struct replace_type_impl<C const, X, Y>{
        typedef typename replace_type<C, X, Y>::type const  type;
    };
    template <typename C, typename X, typename Y>
    struct replace_type_impl<C volatile, X, Y>{
        typedef typename replace_type<C, X, Y>::type volatile  type;
    };
    template <typename C, typename X, typename Y>
    struct replace_type_impl<C *, X, Y>{
        typedef typename replace_type<C, X, Y>::type *  type;
    };
    
    template <typename C, typename X, typename Y>
    struct replace_type_impl<C &, X, Y>{
        typedef typename replace_type<C, X, Y>::type &  type;
    };
    
    template <typename C, typename X, typename Y>
    struct replace_type_impl<C &&, X, Y>{
        typedef typename replace_type<C, X, Y>::type &&  type;
    };
    
    template <typename C, typename X, typename Y>
    struct replace_type_impl<C[], X, Y>{
        typedef typename replace_type<C, X, Y>::type type[];
    };
    
    template <typename C, typename X, typename Y, unsigned N>
    struct replace_type_impl<C [N], X, Y>{
        typedef typename replace_type<C, X, Y>::type type[N];
    };
    
    template <typename C, typename Class, typename X, typename Y>
    struct replace_type_impl<C Class::*, X, Y>{
        typedef typename replace_type<C, X, Y>::type Class::* type;
    };
    
    
    template <typename R, typename X, typename Y,typename... Args>
    struct replace_type_impl<R(Args...), X, Y>{
        typedef typename replace_type<R, X, Y>::type type(typename replace_type<Args, X, Y>::type...);
    };
    
    }

    2. 测试

     1 #include <type_traits>
     2 #include <gtest/gtest.h>
     3 
     4 #define MYTEST(Res, C, X , Y) EXPECT_TRUE((std::is_same<Res, xusd::replace_type<C, X, Y>::type >::value))
     5 
     6 TEST(TestReplaceType, TestSimple){
     7     EXPECT_TRUE((std::is_same<int*, xusd::replace_type<void*, void, int>::type >::value));
     8     MYTEST(int*, void*, void, int);
     9     MYTEST(long*[10], int const*[10], int const, long);
    10 
    11     MYTEST(int const *[10], int const*[10], char, long);
    12 }
    13 
    14 TEST(TestReplaceType, TestSameType){
    15     MYTEST(int const*[10], int const*[10], int const, int const); // X == Y
    16 
    17     MYTEST(long , int const*[10], int const*[10], long); // C == X
    18 }
    19 
    20 
    21 TEST(TestReplaceType, TestClass){
    22     class A;
    23     MYTEST(long A::* , int A::*, int, long);
    24 
    25     MYTEST(long (A::*)(char, long) , int (A::*)(char, int), int, long);
    26 }
    27 TEST(TestReplaceType, TestReference){
    28     MYTEST(long&&, int&&, int, long);
    29     MYTEST(long const&&, int const&&, int, long);
    30     MYTEST(long&, int&, int, long);
    31     MYTEST(long const&, int const&, int, long);
    32 
    33 }
    34 TEST(TestReplaceType, TestArray){
    35     MYTEST(double[], int[], int , double);
    36     MYTEST(double[10], int[10], int , double);
    37 }
    38 //TEST(TestReplaceType, TestSimple){}
    39 TEST(TestReplaceType, TestFuntion){
    40     EXPECT_TRUE((std::is_same<long&(*)(long&), xusd::replace_type<char&(*)(char&), char&, long&>::type >::value));
    41     EXPECT_TRUE((std::is_same<long&(*)(long&, long&), xusd::replace_type<char&(*)(char&, char&), char&, long&>::type >::value));
    42     EXPECT_TRUE((std::is_same<long&(*)(long&, long&, long&), xusd::replace_type<char&(*)(char&, char&, char&), char&, long&>::type >::value));
    43     EXPECT_TRUE((std::is_same<long&(*)(long&, long&, long&, long&), xusd::replace_type<char&(*)(char&, char&, char& , char&), char&, long&>::type >::value));
    44 
    45     EXPECT_TRUE((std::is_same<int&, xusd::replace_type<void (&)(int, long, double), void(int, long, double), int>::type >::value));
    46     EXPECT_TRUE((std::is_same<int*, xusd::replace_type<void (*)(int, long, double), void(int, long, double), int>::type >::value));
    47 
    48     EXPECT_TRUE((std::is_same<int(*)(char, char), xusd::replace_type<void (*)(int, long, double), void(int, long, double), int(char, char)>::type >::value));
    49 }
    50 
    51 
    52 int main(int argc, char* argv[]){
    53     
    54     testing::InitGoogleTest(&argc, argv);
    55     return RUN_ALL_TESTS();
    56 }
    View Code
  • 相关阅读:
    Git windows换行问题
    java之aop使用及自定义注解
    Shiro授权及注解式开发
    Git Gui、Ssh key的使用和ideaui配置使用Git解决冲突(下)
    Git和Github的介绍、简单操作、冲突(上)
    Shiro身份认证、盐加密
    Shiro简介、入门案例、web容器的集成
    SpringMVC入门
    Mybatis之关联关系(一对多、多对多)
    Mybatis整合(Redis、Ehcache)实现二级缓存
  • 原文地址:https://www.cnblogs.com/xusd-null/p/3704405.html
Copyright © 2011-2022 走看看