今天有一同学在群上聊到一个比较好玩的题目(本人看书不多,后面才知是《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. 【转】Bellman_ford算法

    原文链接:http://www.cnblogs.com/Jason-Damon/archive/2012/04/21/2460850.html 摘自百度百科 Bellman-ford算法是求含负权图的 ...

  2. (转载)OC学习篇之---Foundation框架中的其他类(NSNumber,NSDate,NSExcetion)

    前一篇说到了Foundation框架中的NSDirctionary类,这一一篇来看一下Foundation的其他常用的类:NSNumber,NSDate,NSException. 注:其实按照Java ...

  3. Google软件测试

    google测试相关的职位有三类:软件测试开发工程师.测试工程师以及测试工程经理. 软件测试开发工程师也是一个开发角色,只是工作重心在可测试性和通用测试框架上.他们参与设计评审,非常近距离地观察代码质 ...

  4. HDU5874:Friends and Enemies

    题目链接: Friends and Enemies 分析: 是一道想法题,我们假设x个人互相敌对,然后有y个人与这x个人都是朋友,而这y个人互相敌对. 则有 x+y=m x*y<=n 举个例子: ...

  5. iOS tableview 优化总结

    根据网络上的优化方法进行了总括.并未仔细进行语言组织.正在这些优化方法进行学习,见另一篇文章 提高app流畅度 1.cell子控件创建写在 initWithStyle:reuseIdentifier ...

  6. 无线网WEP的安全测试及防范

    650) this.width=650;" border="0" alt="" src="http://img1.51cto.com/att ...

  7. VS2010 删除空行

    查找内容:^:b*$\n 替换为: 查找范围:当前文档 使用:正则表达式 vs2013 ^\s*(?=\r?$)\n

  8. SQL2008 SQL Server 代理服务提供的凭据无效

    工作中遇到的问题记录: 安装到服务器配置时出的错误:为 SQL Server 代理服务提供的凭据无效.若要继续操作,请为 SQL Server 代理服务提供有效的帐户和密码. 解决方法:直接在所有的“ ...

  9. labview图形和图表的类型

    http://zone.ni.com/reference/zhs-XX/help/371361L-0118/lvconcepts/types_of_graphs_and_charts/ LabVIEW ...

  10. [iOS微博项目 - 3.1] - 发微博界面

    github: https://github.com/hellovoidworld/HVWWeibo   A.发微博界面:自定义UITextView 1.需求 用UITextView做一个编写微博的输 ...