假设我有一个模板函数,它接受一个整数和一个对类型 T 实例的 const 引用。现在根据整数,只有一些 T 是可接受的,否则在运行时会引发异常。
如果此函数的所有使用都使用常量整数,则可以使 int 成为模板参数并使用静态断言来检查它是否可以接受。所以不是func(1,c)
一个人会使用func<1>(c)
并且会获得编译时类型检查。有什么方法可以编写func(1,c)
并保持编译时检查,同时还可以编写func(i,c)
和使用动态断言?目标是使其对开发人员透明。添加这种安全性而无需为诸如编译时常量之类的事情打扰开发人员就太好了。他们可能只记得func(1,c)
总是有效并使用它,避免检查。
如何尽可能使用静态断言和动态断言定义函数?
以下代码显示了Ivan Shcherbakov的 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 的代码。