我有一个要求,如果作为模板参数之一传递的整数大于某个值,我应该使用特定的类。否则,我应该得到一个编译时错误...
类似下面的内容:
enum Time { Day, Week, Month };
template<Time t, int length>
class Timer
{
}
现在,我必须限制实例化 Timer
以这样的方式——
Timer<Day,8>
, Timer<Day,9>
等应该可以,但是 length
与 Day
一起使用时不能小于 8 .
同样,length
与 Week
一起使用时不能小于 10等等……
有人可以帮我解决如何在编译时实现这一点吗?
最佳答案
所有其他答案都用于元编程来检测条件,另一方面,我会保持简单:
template<Time t, int length>
class Timer
{
static_assert( (t == Day && length > 7)
||(t == Week && length > 10)
||(t == Month && length > 99), "Invalid parameters"
};
如果不满足条件,编译器将触发断言,通过错误消息和/或查看行来验证非常简单。
使用 SFINAE 工具禁用该类型的版本也确实达到了相同的结果:代码不会编译,但代价是使错误消息更难以阅读:这意味着什么 Timer<Day,5>
是不是一个类型?肯定是,它是Timer<Time,int>
的实例化!
编辑:以上 static_assert
在 C++0x 中实现,在没有 C++0x 的编译器中你可以实现 static_assert
作为宏:
#define static_assert( cond, name ) typedef char sassert_##name[ (cond)? 1 : -1 ];
这个简单的宏不接受字符串文字作为第二个参数,而是接受单个单词。用法是:
static_assert( sizeof(int)==4, InvalidIntegerSize ) )
并且错误消息需要一些人工解析,因为编译器会提示(如果不满足条件)sassert_InvalidIntegerSize
的大小是负的。
关于c++ - 模板参数的编译时间比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6530747/