假设我有一个模板函数,它接受一个整数和一个对类型 T 的实例的 const 引用。现在,根据整数,只有某些 T 是可接受的,否则在运行时会引发异常。
如果此函数的所有使用都使用常量整数,则可以将 int 设为模板参数并使用静态断言来检查它是否可接受。所以而不是func(1,c)
有人会用func<1>(c)
并将获得编译时类型检查。有什么办法可以写func(1,c)
并仍然保留编译时检查,同时也能够编写func(i,c)
并使用动态断言?目标是使其对开发人员透明。如果能够添加这种安全性而不用担心开发人员担心编译时常量之类的事情,那就太棒了。他们可能只会记得func(1,c)
总是有效并使用它,避免检查。
如何尽可能使用静态断言定义函数,否则使用动态断言?
以下代码显示了 GCC 的解决方案:伊万·谢尔巴科夫:
#include <iostream>
#include <cassert>
template<typename T>
void __attribute__((always_inline)) func(const int& i, const T& t);
void compile_time_error_() __attribute__((__error__ ("assertion failed")));
template<>
void __attribute__((always_inline))
func(const int& i, const float& t)
{
do {
if (i != 0) {
if (__builtin_constant_p(i)) compile_time_error_();
std::cerr << "assertion xzy failed" << std::endl;
exit(1);
}
} while (0);
func_impl<float>(i,t);
}
这仅允许 i=0 和 T=float 的组合。对于其他组合,一个好方法是创建一个宏来生成以下代码template<> func(const int& i, const T& t)
用 T 和 i != 0 替换。