我有一个要求,如果作为模板参数之一传递的整数大于某个特定值,我应该使用特定的类。否则,我会得到一个编译时错误...
它类似于以下内容:
enum Time { Day, Week, Month };
template<Time t, int length>
class Timer
{
}现在,我必须限制实例化Timer的方式,以便-
Timer<Day,8>、Timer<Day,9>等应可用,但与Day配合使用时,length不能小于8。
同样,当与Week等一起使用时,length不能小于10。
有人能帮我讲讲如何在编译时实现这一点吗?
发布于 2011-06-30 14:39:39
将length >= 8的结果作为bool模板参数传递给辅助模板。仅为true提供专业化认证。话虽如此,这听起来像是家庭作业,所以我将把编码留给你。
干杯。
发布于 2011-06-30 15:37:57
所有其他答案都适用于元编程来检测条件,另一方面,我会让事情变得简单:
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的大小为负数。
发布于 2011-06-30 15:08:12
您可以这样做:
template<bool>
struct rule;
template<>
struct rule<true> {};
template<Time Tm, int Len>
struct constraint;
//Rule for Day
template<int Len>
struct constraint<Day, Len> : rule<(Len>= 8)>
{};
template<Time Tm, int Len>
class Timer : constraint<Tm, Len>
{
//your code
};测试代码:
int main() {
Timer<Day, 7> timer1; //error
Timer<Day, 8> timer2; //okay
return 0;
}在线演示:
Timer<Day, 7> timer1:已评论的)Timer<Day, 7> timer1:未已评论)同样,您可以为Week和Month添加规则,如下所示:
//Rule for Week
template<int Len>
struct constraint<Week, Len> : rule<(Len>= 10)>
{};
//Rule for Month
template<int Len>
struct constraint<Month, Len> : rule<(Len>= 100)>
{};https://stackoverflow.com/questions/6530747
复制相似问题