一道模板元编程题源码解答(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*[]
, 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)的更多相关文章
- 读书笔记_Effective_C++_条款四十八:了解模板元编程
作为模板部分的结束节,本条款谈到了模板元编程,元编程本质上就是将运行期的代价转移到编译期,它利用template编译生成C++源码,举下面阶乘例子: template <int N> st ...
- effective c++ Item 48 了解模板元编程
1. TMP是什么? 模板元编程(template metaprogramming TMP)是实现基于模板的C++程序的过程,它能够在编译期执行.你可以想一想:一个模板元程序是用C++实现的并且可以在 ...
- 读书笔记 effective c++ Item 48 了解模板元编程
1. TMP是什么? 模板元编程(template metaprogramming TMP)是实现基于模板的C++程序的过程,它能够在编译期执行.你可以想一想:一个模板元程序是用C++实现的并且可以在 ...
- 初识C++模板元编程(Template Mega Programming)
前言:毕设时在开源库上做的程序,但是源码看得很晕(当时导师告诉我这是模板元编程,可以不用太在乎),最近自己造轮子时想学习STL的源码,但也是一样的感觉,大致了解他这么做要干什么,但是不知道里面的机制. ...
- 初识c++模板元编程
模板元编程(Template metaprogramming,简称TMP)是编译器内执行的程序,编译器读入template,编译输出的结果再与其他源码一起经过普通编译过程生成目标文件.通俗来说,普通运 ...
- C++ 模板元编程 学习笔记
https://blog.csdn.net/K346K346/article/details/82748163 https://www.jianshu.com/p/b56d59f77d53 https ...
- C++模板元编程(C++ template metaprogramming)
实验平台:Win7,VS2013 Community,GCC 4.8.3(在线版) 所谓元编程就是编写直接生成或操纵程序的程序,C++ 模板给 C++ 语言提供了元编程的能力,模板使 C++ 编程变得 ...
- C++模板元编程 - 函数重载决议选择工具(不知道起什么好名)完成
这个还是基于之前实现的那个MultiState,为了实现三种类型“大类”的函数重载决议:所有整数.所有浮点数.字符串,分别将这三种“大类”的数据分配到对应的Converter上. 为此实现了一些方便的 ...
- C++模板元编程 - 挖新坑的时候探索到了模板元编程的新玩法
C++真是一门自由的语言,虽然糖没有C#那么多,但是你想要怎么写,想要实现什么,想要用某种编程范式或者语言特性,它都会提供. 开大数运算类的新坑的时候(又是坑),无意中需要解决一个需求:大数类需要分别 ...
随机推荐
- Basic Sorting Algorithms
*稳定指原本数列中相同的元素的相对前后位置在排序后不会被打乱 快速排序(n*lgn 不稳定):数组中随机选取一个数x(这里选择最后一个),将数组按比x大的和x小的分成两部分,再对剩余两部分重复这个算法 ...
- 调用openoffice Com组件转换成PDF
//例子 OpenOfficeExportToPDF('file:///C:/SourceFile.odt', 'file:///C:/TargetFile.pdf'); 必须为URL格式的路径 ...
- (翻译)从底层了解ASP.NET体系结构 [转]
转自:http://www.cnblogs.com/rijing2004/archive/2007/09/14/howaspnetwork.html 前言 关于ASP.NET的底层的工作机制,最近园子 ...
- ipc.Client: Retrying connect to server: h1/192.168.1.61:9000. Already tried 0 time(s);解决方法
1.检查namenode服务器的是否运行正常,我的问题是没有开启hadoop集群出现的. 2.检查namenode服务器的防火墙是否开放的响应端口,一般内网建议关闭.
- ssh-keygen
- xe mysql
[FireDAC][Phys][MySQL]-314. Cannot load vendor library [libmysql.dll or libmysqld.dll]. The specifie ...
- maven 部署到tomcat 的 resource问题
1.maven resource结构 如图,我将resoures下建立四个子文件夹,base存放的是不随环境变化的配置项,而其他三个均是对应环境的配置文件. 2.问题 我执行maven命令是没有的,但 ...
- hdu 5655 CA Loves Stick
CA Loves Stick Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) ...
- linux极点五笔无法输入词组_ibus设置
菜鸟学linux——用的是ubuntu 不知道是不是按个哪些快捷键,极点五笔突然无法输入词组.那个抓狂啊 没关系,设置一下就ok 第一步:右上角输入法,右键——>首选项——>常规——> ...
- oracle学习 四(持续更新中)无法为表空间 MAXDATA 中的段创建 INITIAL 区
解决建立表的时候出现的 ORA-01658: 无法为表空间 MAXDATA 中的段创建 INITIAL 区 出现这个问题是因为表空间的大小不足,可以给他扩容这样的话也会多出来一个数据文件.具体写法如下 ...