Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板参数的编译时比较_C++_Templates_Comparison - Fatal编程技术网

C++ 模板参数的编译时比较

C++ 模板参数的编译时比较,c++,templates,comparison,C++,Templates,Comparison,我有一个要求,如果作为模板参数之一传递的整数大于某个值,我应该使用特定的类。否则,我会得到一个编译时错误 它类似于以下内容: enum Time { Day, Week, Month }; template<Time t, int length> class Timer { } 枚举时间{天、周、月}; 模板 班级计时器 { } 现在,我必须限制实例化计时器,以使- 定时器,定时器等应该可以工作,但是长度与日期一起使用时不能小于8 类似地,length与Week等一起使用时不能

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

它类似于以下内容:

enum Time { Day, Week, Month };

template<Time t, int length>
class Timer
{
}
枚举时间{天、周、月};
模板
班级计时器
{
}
现在,我必须限制实例化
计时器
,以使-

定时器
定时器
等应该可以工作,但是
长度
日期
一起使用时不能小于8

类似地,
length
Week
等一起使用时不能小于10


有人能帮助我在编译时如何实现这一点吗?

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


干杯&hth.

这种验证的想法通常是将工作交给一个专用的助手类,您专门为每种参数指定该类

template <typename T, size_t V>
class Foo
{
  static_assert(helper<T,V>::value, "Wrong Parameters");
};
模板
福班
{
静态断言(helper::value,“错误参数”);
};
有两种方法可以执行验证:

// 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> {};
//需要完全专门化
模板结构帮助器:std::false_type{};
模板
结构助手:std::true_type{};
模板
结构助手:std::true_type{};
//财产状
模板结构帮助器:std::false_type{};
模板
struct helper:std::integral_constant您可以执行以下操作:

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
};

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

template<Time t, int length>
class Timer
{
    static_assert( (t == Day && length > 7) 
                 ||(t == Week && length > 10)
                 ||(t == Month && length > 99), "Invalid parameters"
};
这个简单的宏不接受字符串文字作为第二个参数,而是接受单个单词。用途如下:

static_assert( sizeof(int)==4, InvalidIntegerSize ) )
错误消息需要一些人工解析,因为编译器会抱怨(如果不满足条件)sassert_invalidIntegrationize的大小为负值。

枚举时间{Day,Week,Month};
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);
};
模板结构长度; 模板结构长度{static const int value=8;}; 模板结构长度{static const int value=9;}; 模板结构长度{static const int value=10;}; 模板结构限制; 模板结构限制{typedef bool yes;}; #定义编译断言(V)类型定义类型名称限制::选中是 模板 班级计时器 { 编译断言(长度>=长度::值); };

请参阅。

Yeap的可能副本,真正的解决方案是使用
静态断言
,您描述的是实现
静态断言
的方法。您应该提到这是C++0x解决方案。OP可能不知道。@Nawaz:static\u assert有不同的风格,有些是C++0x,有些不是。
static_assert
的最简单实现是
#定义static_assert(cond,name)typedef char sassert##name[(cond)?1:-1]
,但这当然不会接受字符串文字作为第二个参数,因此它将用作:
静态断言(…,InvalidParameters)
,并且错误消息会稍差一些,类似于
数组'sassert\u InvalidParameters'的大小为负。我们目前使用的宏与我们的代码库中的宏相似,并且编译器不支持C++0x。如果采用这种风格,那么错误消息就没有您最初的帖子所说的那么好。现在,模板元编程在“有用的错误消息”方面与此解决方案一样好。@Nawaz:错误消息将包含一个已知的字符串
sassert\uuu
,后跟一个描述性的含义
InvalidParameters
(当然,无效参数并不是描述性的,但
InvalidTimerPeriod
可能是)。另一方面,在TMP方法中,您得到的只是未定义类型X的
无效使用(阅读测试中的错误消息)。您是否使用了转发声明,但忘记包含适当的类型?还是条件不正确?为什么有人投诉
规则
?我哪里都不用!静态断言将指向检查失败的确切行。整个概念提案和C++编译器所发布的错误消息的许多抱怨都是相同的问题:错误消息指向了在代码中没有使用的实现的一些细节,甚至没有告诉您底层的内容。问题是。概念的想法是,它们的行为类似于静态断言或类型中所需的特性,而不是模板化代码中更深层次的错误,在模板化代码中,错误更难被人类解释,从而产生更好的错误报告。
#define static_assert( cond, name ) typedef char sassert_##name[ (cond)? 1 : -1 ];
static_assert( sizeof(int)==4, InvalidIntegerSize ) )
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);
};