模板参数的编译时间比较
Compile time comparison of template parameter
我有一个要求,如果作为模板参数之一传递的整数大于某个值,我应该使用特定的类。否则,我会得到一个编译时错误。。。
它类似于以下内容:
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…
有人能帮助我了解如何在编译时实现这一点吗?
所有其他答案都用于元编程来检测条件,另一方面我会保持简单:
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>
的实例化
EDIT:上面的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
的大小为负数。
将length >= 8
的结果作为bool
模板参数传递给助手模板。仅为true
提供专业化。话虽如此,这听起来像是家庭作业,所以我将把编码留给你。
干杯&hth。
您可以这样做:
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;
}
在线演示:
- http://www.ideone.com/tSBhG(
Timer<Day, 7> timer1
:已发表评论( - http://www.ideone.com/mbN6m(
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)>
{};
这种验证的想法通常是将工作交给一个专用的助手类,您可以为每种参数专门化该助手类。
template <typename T, size_t V>
class Foo
{
static_assert(helper<T,V>::value, "Wrong Parameters");
};
有两种方法可以进行验证:
// Require full specialization
template <typename T, size_t V> struct helper: std::false_type {};
template <>
struct helper<Bar,0>: std::true_type {};
template <>
struct helper<Bar,4>: std::true_type {};
// Property like
template <typename T, size_t V> struct helper: std::false_type {};
template <size_t V>
struct helper<Bar, V>: std::integral_constant<bool, V <= 8> {};
当然,这些假设是C++0x设施。在C++03中,您必须自己提供简单的true_type
、false_type
和integral_constant
类。
enum Time { Day, Week, Month };
template<Time T> struct Length;
template<> struct Length<Day> { static const int value = 8 ; };
template<> struct Length<Week> { static const int value = 9; };
template<> struct Length<Month> { static const int value = 10; };
template<bool b> struct Limit;
template<> struct Limit<true> { typedef bool yes; };
#define COMPILE_ASSERT(V) typedef typename Limit<(V)>::yes checked
template<Time t, int length>
class Timer
{
COMPILE_ASSERT(length >= Length<t>::value);
};
请参阅此处的演示。
- 为什么字符串比较的 == 运算符相对于任一字符串长度线性时间(似乎)?
- 比较向量中的元素时所花费的时间呈指数级增长
- 与操作员比较两个计时时间点
- 如何使用 CTIME/Chrono Libarey 将开始时间与系统时钟进行比较
- 将系统时间与变量进行比较 - C++
- 如何比较两个经过的时间?
- Rcpp/C++/R:比较日期时间矢量与日期时间时出错(错误:"运算符>"的不明确重载)
- C++ - 仅比较时间
- 比较12小时格式时间
- 使用计时比较C++的持续时间/秒数并不像预期的那样工作
- C++:将当前时间与下一个工作时间进行比较
- 通用恒定时间比较函数C
- 将当前时间 simTime.dbl() 与以前存储的双精度值进行比较并不总是给出正确的答案......为什么?
- 比较向量元件的运行时间复杂性的提高
- 可靠地比较不同机器的时间戳C++
- 运行时间比较 - 类似的代码运行速度慢 4 倍
- 如何测量C代码的运行时间比较
- 在c++11中进行相对时间比较的最干净的方法
- 这是c++和Python之间CPU时间比较的有效方法吗?
- 模板参数的编译时间比较