这两小节放在一起讲,目的都是解决C++98模板编程时的一些遗留问题,作为后面介绍的特性(比如decltype)的前提。
使用using对模板起别名
C++11对using的用法进行了扩展,可以代替typedef,并且比typedef功能更强。
以下是用using替代typedef的例子,is_same检查两个类型是否相同,结果是相同的。
#include <iostream>
#include <type_traits>
using namespace std;
using uint = unsigned int;
typedef unsigned int UINT;
using sint = int;
int main() {
cout << is_same<uint, UINT>::value << endl; // 1
}
以下的例子展示了using比typedef功能更强的地方,支持“模板式”地使用。
#include <map>
using namespace std;
template<typename T> using MapString = std::map<T, char*>;
int main() {
MapString<int> numberedString;
}
一般化的SFINEA规则
C++模板中,有一条著名的规则SFINAE,Substitution failure is not an error,直译是匹配失败不是错误,通俗地说,在对重载地模板参数进行展开时,如果展开导致了类型不匹配,编译器并不会报错。
因为C++98标准对于SFINAE没有完全清晰的描述,一些在模板参数中使用表达式的情况,并没有被主流编译器支持。
template <int I> struct A {};
char xxx(int);
char xxx(float);
template <class T> A<sizeof(xxx((T)0))> f(T) {}
int main (){
f(1);
}
// 实测g++的98和11都可以编译通过,估计是g++的特殊处理
这个例子我其实没看明白是在做什么。
网友评论