模板元程序中的编译时验证错误

时间:2019-01-18 14:57:41

标签: c++

尝试在编译时编写一个简单的验证器,以检查给定的数量是否在以下定义的范围内。

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'

有什么想法吗?

3 个答案:

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

try it out here

答案 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