static_assert提供一个编译时的断言检查。如果断言为真,什么也不会发生。如果断言为假,编译器会打印一个特殊的错误信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
template < typename T, size_t Size>
class Vector
{ static_assert(Size < 3, "Size is too small" );
T _points[Size];
}; int main()
{ Vector< int , 16> a1;
Vector< double , 2> a2;
return 0;
} |
1
2
3
4
5
6
7
|
error C2338: Size is too small see reference to class template instantiation 'Vector<T,Size>' being compiled with
[
T=double,
Size=2
]
|
static_assert和type traits一起使用能发挥更大的威力。type traits是一些class,在编译时提供关于类型的信息。在头文件<type_traits>中可以找到它们。这个头文件中有好几种class: helper class,用来产生编译时常量。type traits class,用来在编译时获取类型信息,还有就是type transformation class,他们可以将已存在的类型变换为新的类型。
下面这段代码原本期望只做用于整数类型。
1
2
3
4
5
|
template < typename T1, typename T2>
auto add(T1 t1, T2 t2) -> decltype(t1 + t2) { return t1 + t2;
} |
但是如果有人写出如下代码,编译器并不会报错
1
2
|
std::cout << add(1, 3.14) << std::endl; std::cout << add( "one" , 2) << std::endl;
|
程序会打印出4.14和”e”。但是如果我们加上编译时断言,那么以上两行将产生编译错误。
1
2
3
4
5
6
7
8
|
template < typename T1, typename T2>
auto add(T1 t1, T2 t2) -> decltype(t1 + t2) { static_assert(std::is_integral<T1>::value, "Type T1 must be integral" );
static_assert(std::is_integral<T2>::value, "Type T2 must be integral" );
return t1 + t2;
} |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
error C2338: Type T2 must be integral see reference to function template instantiation 'T2 add<int,double>(T1,T2)' being compiled with
[
T2=double,
T1=int
]
error C2338: Type T1 must be integral see reference to function template instantiation 'T1 add<const char*,int>(T1,T2)' being compiled with
[
T1=const char *,
T2=int
]
|