今天有一同学在群上聊到一个比较好玩的题目(本人看书不多,后面才知是《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*[]
, 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. 测试

 #include <type_traits>
#include <gtest/gtest.h> #define MYTEST(Res, C, X , Y) EXPECT_TRUE((std::is_same<Res, xusd::replace_type<C, X, Y>::type >::value)) TEST(TestReplaceType, TestSimple){
EXPECT_TRUE((std::is_same<int*, xusd::replace_type<void*, void, int>::type >::value));
MYTEST(int*, void*, void, int);
MYTEST(long*[], int const*[], int const, long); MYTEST(int const *[], int const*[], char, long);
} TEST(TestReplaceType, TestSameType){
MYTEST(int const*[], int const*[], int const, int const); // X == Y MYTEST(long , int const*[], int const*[], long); // C == X
} TEST(TestReplaceType, TestClass){
class A;
MYTEST(long A::* , int A::*, int, long); MYTEST(long (A::*)(char, long) , int (A::*)(char, int), int, long);
}
TEST(TestReplaceType, TestReference){
MYTEST(long&&, int&&, int, long);
MYTEST(long const&&, int const&&, int, long);
MYTEST(long&, int&, int, long);
MYTEST(long const&, int const&, int, long); }
TEST(TestReplaceType, TestArray){
MYTEST(double[], int[], int , double);
MYTEST(double[], int[], int , double);
}
//TEST(TestReplaceType, TestSimple){}
TEST(TestReplaceType, TestFuntion){
EXPECT_TRUE((std::is_same<long&(*)(long&), xusd::replace_type<char&(*)(char&), char&, long&>::type >::value));
EXPECT_TRUE((std::is_same<long&(*)(long&, long&), xusd::replace_type<char&(*)(char&, char&), char&, long&>::type >::value));
EXPECT_TRUE((std::is_same<long&(*)(long&, long&, long&), xusd::replace_type<char&(*)(char&, char&, char&), char&, long&>::type >::value));
EXPECT_TRUE((std::is_same<long&(*)(long&, long&, long&, long&), xusd::replace_type<char&(*)(char&, char&, char& , char&), char&, long&>::type >::value)); EXPECT_TRUE((std::is_same<int&, xusd::replace_type<void (&)(int, long, double), void(int, long, double), int>::type >::value));
EXPECT_TRUE((std::is_same<int*, xusd::replace_type<void (*)(int, long, double), void(int, long, double), int>::type >::value)); EXPECT_TRUE((std::is_same<int(*)(char, char), xusd::replace_type<void (*)(int, long, double), void(int, long, double), int(char, char)>::type >::value));
} int main(int argc, char* argv[]){ testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

一道模板元编程题源码解答(replace_type)的更多相关文章

  1. 读书笔记_Effective_C++_条款四十八:了解模板元编程

    作为模板部分的结束节,本条款谈到了模板元编程,元编程本质上就是将运行期的代价转移到编译期,它利用template编译生成C++源码,举下面阶乘例子: template <int N> st ...

  2. effective c++ Item 48 了解模板元编程

    1. TMP是什么? 模板元编程(template metaprogramming TMP)是实现基于模板的C++程序的过程,它能够在编译期执行.你可以想一想:一个模板元程序是用C++实现的并且可以在 ...

  3. 读书笔记 effective c++ Item 48 了解模板元编程

    1. TMP是什么? 模板元编程(template metaprogramming TMP)是实现基于模板的C++程序的过程,它能够在编译期执行.你可以想一想:一个模板元程序是用C++实现的并且可以在 ...

  4. 初识C++模板元编程(Template Mega Programming)

    前言:毕设时在开源库上做的程序,但是源码看得很晕(当时导师告诉我这是模板元编程,可以不用太在乎),最近自己造轮子时想学习STL的源码,但也是一样的感觉,大致了解他这么做要干什么,但是不知道里面的机制. ...

  5. 初识c++模板元编程

    模板元编程(Template metaprogramming,简称TMP)是编译器内执行的程序,编译器读入template,编译输出的结果再与其他源码一起经过普通编译过程生成目标文件.通俗来说,普通运 ...

  6. C++ 模板元编程 学习笔记

    https://blog.csdn.net/K346K346/article/details/82748163 https://www.jianshu.com/p/b56d59f77d53 https ...

  7. C++模板元编程(C++ template metaprogramming)

    实验平台:Win7,VS2013 Community,GCC 4.8.3(在线版) 所谓元编程就是编写直接生成或操纵程序的程序,C++ 模板给 C++ 语言提供了元编程的能力,模板使 C++ 编程变得 ...

  8. C++模板元编程 - 函数重载决议选择工具(不知道起什么好名)完成

    这个还是基于之前实现的那个MultiState,为了实现三种类型“大类”的函数重载决议:所有整数.所有浮点数.字符串,分别将这三种“大类”的数据分配到对应的Converter上. 为此实现了一些方便的 ...

  9. C++模板元编程 - 挖新坑的时候探索到了模板元编程的新玩法

    C++真是一门自由的语言,虽然糖没有C#那么多,但是你想要怎么写,想要实现什么,想要用某种编程范式或者语言特性,它都会提供. 开大数运算类的新坑的时候(又是坑),无意中需要解决一个需求:大数类需要分别 ...

随机推荐

  1. 30+学习Web设计和开发的优质新鲜资源

    今天我们整理了一些最新的Web设计和开发的资源,这些资源都来自国外的流行站点,不过大家应该不会陌生,放在这里供大家收藏,在需要的时候方便翻阅和学习! 原文地址:http://www.goodfav.c ...

  2. APIO2014 爆零总结

    真心爆零 不要不服 这次apio给了一种新的赛制 看上去很好? 所有人都可以在线提交 并且实时知道自己的分数 它对每个题目分成若干分数段 每个分数段有若干数据 要获得这个分数段的分数需要通过这个分数段 ...

  3. 应用引擎BAE3.0(转)

    add by zhj: 其实我主要是想看看基于docker的PaaS的特性. 原文:http://developer.baidu.com/wiki/index.php?title=docs/cplat ...

  4. Linux操作系统时间与BIOS硬件时间

    注:以Ubuntu为例说明 在Linux计算机上,有两个时间,一个是硬件时间(BIOS中记录的时间,称为hwclock),另一个是操作系统时间(osclock).硬件时钟由BIOS电池供电, 当计算机 ...

  5. HDU 5862 Counting Intersections (树状数组)

    Counting Intersections 题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 Description Given ...

  6. IMAQdx和IMAQ

    NI-IMAQdx driver software gives you the ability to acquire images with IEEE 1394 and GigE Vision cam ...

  7. [原创]mac终端前面的计算机名怎么改??

    1.修改-之前的名称 mac环境,系统 OS X Yisemite,打开终端, 执行下面命令“Tmp”是你想要改的电脑名称 sudo scutil --set HostName Tmp 执行前,执行后 ...

  8. JPA 原生态SQL 的复杂查询之createNamedQuery

    JPA 原生态SQL 的复杂查询之createNamedQuery调用存储过程,返回的List字段对应的填充实体============实体类,调用存储过程====================== ...

  9. 结构类模式(三):组合(Composite)

    定义 将对象组合成树形结构以表示“部分整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性. 有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客 ...

  10. OC:属性、点语法、KVC

    //属性的属性 属性定义在一个 .h文件里,在这个.h文件里可以定义实例变量(就是这个类的特征),也可以通过   @protery(属性约束关键字) 属性名字类型 属性名 来定义一些属性,在prope ...