尝试在编译时编写一个简单的验证器,以检查给定的数量是否在以下定义的范围内。
template<unsigned N> struct valid {static const unsigned value = 0; };
template<0U> struct valid {static const unsigned value = 1; };
template<99U> struct valid {static const unsigned value = 1; };
template<unsigned N> struct validate
{
static const unsigned value = valid< std::min<0U,N> >::value *
valid< std::max<N,99U> >::value;
}
但是,以上操作失败- 错误:无法将模板参数'min <0u,1u>'转换为'unsigned int' 错误:无法将模板参数'max <1u,99u>'转换为'unsigned int'
有什么想法吗?
答案 0 :(得分:6)
首先,以上代码不是有效的C ++代码。您用于显式模板专业化的语法不正确(并且结尾缺少分号)。除此之外:std::min<0U,N>
和std::max<N,99U>
是函数,而不是函数调用。您可能打算写:
template<unsigned N> struct valid {static const unsigned value = 0; };
template<> struct valid<0U> {static const unsigned value = 1; };
template<> struct valid<99U> {static const unsigned value = 1; };
template<unsigned N> struct validate
{
static const unsigned value = valid< std::min(0U,N) >::value *
valid< std::max(N,99U) >::value;
};
答案 1 :(得分:2)
为什么不简单地写:
template <unsigned N, unsigned LO = 0U, unsigned HI = 99U>
struct validate : std::bool_constant< N>=LO && N<=HI >
{ /* static_assert(LO <= HI); */ };
请注意,unsigned
类型的任何值都将大于或等于0。
答案 2 :(得分:2)
作为其他人提出的替代方案,在C ++ 11中,您可以为此目的使用constexpr
:
constexpr bool is_in_range (unsigned n, unsigned low = 0u, unsigned high = 99u) {
return low <= n && n <= high;
}
您可以通过在需要这种评估的上下文中使用它来强制在编译时求值(如果所有参数在编译时都是已知的),例如:
static_assert(is_in_range(5u), ""); // can skip the message with C++17