constexpr函数内部的if vs if constexpr [英] if vs if constexpr inside constexpr function

查看:796
本文介绍了constexpr函数内部的if vs if constexpr的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我在constexpr函数中将某些if constexpr修改为if,发现它们仍然可以正常工作,并且可以在编译时进行评估.这是一个最小的情况:

Recently I modify some if constexpr into if in my constexpr functions and found they still work fine and can be evaluated when compile time. Here is a minimum case:

template<int N>
constexpr bool is_negative()
{
    if constexpr  (N >= 0) return false;
    else  return true; 
}
int main()
{
    constexpr  bool v = is_negative<1>();
}

live demo

在上述情况下,由于N是非类型模板参数,因此必须在编译时知道它,因此if constexpr在这里可以正常工作.但是,它是一个constexpr函数,因此iirc,即使我将if constexpr替换为if:

In the case above, N must be known at compile time because it is non-type template parameter, so if constexpr works fine here. However, it is a constexpr function, so, iirc, it is possible to get a return value even though I replace if constexpr with if:

template<int N>
constexpr bool is_negative()
{
    if  (N >= 0) return false;
    else  return true; 
}
int main()
{
    constexpr  bool v = is_negative<1>();
}

> live demo

cppref 中,A constexpr function must satisfy the following requirements:中的所有要求都不会提if.因此,对于IIUC,即使所有相关变量在编译时都是已知的(例如上面的is_negative),constexpr函数是否包含要在编译时求值的if都应该是实现定义的行为.

From cppref, all of the requirements in A constexpr function must satisfy the following requirements: don't mention if. So, IIUC, it should be implementation defined behavior whether constexpr function contain if to be evaluted at compile time even though all related variable is known at compile time(like is_negative above).

所以,我的结论是:

  • 在c ++ 17之前,我们没有if constexpr,所以选择的是if,这意味着不能保证在编译时对constexpr函数进行求值,而这一切都取决于编译器的实现
  • 在c ++ 17之后,如果希望在编译时评估constexpr函数,则首选if constexpr.
  • Before c++17, we don't have if constexpr, so the choice is if, which means it is not guaranteed to get our constexpr functions get evaluted at compile time, all depend on compiler implementation
  • After c++17, if constexpr is preferred if we want constexpr functions get evaluated at compile time.

以上全部是我的个人想法,也许是一些重要的遗漏/误解,可以随时纠正我.问题仍然没有改变:ifif constexpr,对于预期在编译时进行评估的constexpr函数,应优先使用它们.

All above is my personal thoughts, maybe something important missed/misunderstand, feel free to correct me. The question is still unchanged: if and if constexpr, which should be prefered for constexpr functions which expected to be evaluated at compile time.

参考: - constexpr函数允许使用什么? -"if constexpr()"之间的差异与"if()"

推荐答案

在c ++ 17之前,我们没有if constexpr,因此选择if,这意味着不能保证在编译时对我们的constexpr函数进行求值,而这一切都取决于编译器的实现

Before c++17, we don't have if constexpr, so the choice is if, which means it is not guaranteed to get our constexpr functions get evaluted at compile time, all depend on compiler implementation

if语句不是constexpr的事实并不意味着它不能在编译时作为constexpr表达式的一部分进行求值.在您的示例中,在两种情况下v都在编译时求值,因为它必须是:它是一个常量表达式.这不是实现的定义.

The fact that an if statement is not constexpr does not mean it can't be evaluated at compile time, as part of a constexpr expression. In your example, v is evaluated at compile time in both cases, because it is required to be: it's a constant expression. That's not implementation defined.

在c ++ 17之后,如果希望constexpr函数在编译时求值,则最好使用constexpr.

After c++17, if constexpr is prefered if we want constexpr functions get evaluated at compile time.

Constexpr if语句用来解决问题.在编译时获取constexpr函数以求值并不是问题.

Constexpr if statements were introduced to solve a problem. Getting constexpr functions to get evaluated at compile time is not that problem.

这里是一个示例,其中需要constexpr if而不是简单的if(摘录自

Here is an example where a constexpr if is required instead of a simple if (taken from cppreference):

template <typename T>
auto get_value(T t) {
    if constexpr(std::is_pointer_v<T>)
        return *t; // deduces return type to int for T = int*
    else
        return t;  // deduces return type to int for T = int
}

尝试删除constexpr关键字并查看会发生什么情况(演示).

Try removing the constexpr keyword and see what happens (demo).

此外,请注意,您始终可以使用其他方法解决该问题,但是if constexpr具有简洁的优点.例如,这是使用标签分派的等效get_value:

Also, note that you can always solve that problem using other methods, but if constexpr has the advantage of conciseness. For instance, here's an equivalent get_value using tag dispatching:

template<typename T>
auto get_value_impl(T t, std::true_type) {
    return *t;
}
template<typename T>
auto get_value_impl(T t, std::false_type) {
    return t;
}

template<typename T>
auto get_value(T t) {
    return get_value_impl(t, std::is_pointer<T>{});
}

演示

这篇关于constexpr函数内部的if vs if constexpr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆