在编译时/模板检查变量的值

时间:2015-12-19 10:15:19

标签: c++ templates c++11 sfinae

所以,我们有这个:

template<typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
void fun(const T& val)
{
    std::cout << "val >= 0";
}

int main()
{
    fun(34);
}

想象一下,我们还有其他函数重载。如果val的值大于0,我怎么才能将上面的函数重载只能编译?

http://en.cppreference.com/w/cpp/types/is_integral上我看到operator()的{​​{1}}超载了,它返回了std::is_integral,所以我尝试了这个:

value

当然,它看起来不对,而且编译器慷慨地告诉我,这是错误的。

如何在编译时检查变量的值?

2 个答案:

答案 0 :(得分:4)

简短的回答:你不能。

函数输入参数值在运行时确定。因此,SFINAE对此没有帮助,也不会有任何其他编译时间的诡计。

你可以做的是在运行时攻击问题,并定义两个相应的函数来启发:

template<typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
void fun(const T& val)
{
    (val < 0)? lower_than_zero(val) : greater_equal_than_zero(val);
}

但可能你已经知道了。如果您还在进行编译时评估,并且您确定您的变量是编译时的野兽。然后你可以将它作为模板非类型参数传递:

template<int N>
std::enable_if_t<N >= 0> fun() {
  std::cout << "N >= 0" << std::endl;
}

template<int N>
std::enable_if_t<N < 0> fun() {
  std::cout << "N < 0" << std::endl;
}

int main() {
  fun<42>();
  fun<-42>();
}

答案 1 :(得分:0)

正如@ 101010所回答的那样,通常无法做到这一点。 但是如果你只需要检查一个条件>= 0,那么你可以这样做:

void ff(unsigned int val) {
    val = 42;
}

int main()
{
    ff(34);
    ff(-34);
}

并像这样编译:

g++ 1.cpp -Werror -Wsign-conversion

但它只是针对一个特例的黑客攻击。