编译模板参数的时间比较

Adi*_*tya 5 c++ comparison templates

我有一个要求,如果作为模板参数之一传递的整数大于某个值,我应该使用特定的类.否则,我应该得到编译时错误...

它类似于以下内容:

enum Time { Day, Week, Month };

template<Time t, int length>
class Timer
{
}
Run Code Online (Sandbox Code Playgroud)

现在,我必须以Timer这样的方式限制实例化-

Timer<Day,8>,Timer<Day,9>等应该工作,但是length当用于不能小于8 Day.

同样,使用length时不能小于Week等等......

有人可以帮我解决一下如何在编译时实现这一目标吗?

Dav*_*eas 7

所有其他答案都用于元编程以检测条件,另一方面我会保持简单:

template<Time t, int length>
class Timer
{
    static_assert( (t == Day && length > 7) 
                 ||(t == Week && length > 10)
                 ||(t == Month && length > 99), "Invalid parameters"
};
Run Code Online (Sandbox Code Playgroud)

如果不满足条件,编译器将触发断言,并且通过错误消息和/或查看该行来验证非常简单.

使用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 ];
Run Code Online (Sandbox Code Playgroud)

这个简单的宏不接受字符串文字作为第二个参数,而是接受单个单词.用法是:

static_assert( sizeof(int)==4, InvalidIntegerSize ) )
Run Code Online (Sandbox Code Playgroud)

并且错误消息需要一些人工解析,因为编译器会抱怨(如果条件不满足),则大小sassert_InvalidIntegerSize为负.


Che*_*Alf 6

length >= 8作为bool模板参数的结果传递给帮助程序模板.true仅提供专业化.话虽如此,这听起来像是家庭作业,所以我会把编码留给你.

干杯和hth.

  • Yeap,真正的解决方案是使用`static_assert`,你所描述的是一种实现`static_assert`的方法. (3认同)