在编译时/模板检查变量的值
Check the value of a variable at compile time / templates
所以,我们有这个:
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()
对于 std::is_integral
过载并且它 returns value
所以我尝试了这个:
template<typename T, typename = std::enable_if_t<std::is_integral<T>::value() > 0>>
当然,它看起来是错误的,而且它是错误的,因为编译器慷慨地让我知道了。
如何在编译时检查变量的值?
简答:你不能。
函数输入参数值在运行时确定。因此,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>();
}
正如@101010 所回答的那样,一般情况下无法做到这一点。
但是如果你只需要检查一个条件>= 0
,那么你可以这样做:
void ff(unsigned int val) {
val = 42;
}
int main()
{
ff(34);
ff(-34);
}
并像这样编译:
g++ 1.cpp -Werror -Wsign-conversion
但这只是一种特殊情况的技巧。
所以,我们有这个:
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()
对于 std::is_integral
过载并且它 returns value
所以我尝试了这个:
template<typename T, typename = std::enable_if_t<std::is_integral<T>::value() > 0>>
当然,它看起来是错误的,而且它是错误的,因为编译器慷慨地让我知道了。
如何在编译时检查变量的值?
简答:你不能。
函数输入参数值在运行时确定。因此,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>();
}
正如@101010 所回答的那样,一般情况下无法做到这一点。
但是如果你只需要检查一个条件>= 0
,那么你可以这样做:
void ff(unsigned int val) {
val = 42;
}
int main()
{
ff(34);
ff(-34);
}
并像这样编译:
g++ 1.cpp -Werror -Wsign-conversion
但这只是一种特殊情况的技巧。