【问题标题】:constexpr and template compile time?constexpr 和模板编译时间?
【发布时间】:2022-01-19 19:21:19
【问题描述】:

我有几个问题!我对模板和 constexpr 及其区别感到困惑。

我知道模板是在编译时实例化的,它们是在编译时执行还是仅在运行时执行?有没有我可以一起使用它们来获得一些好处的例子?

如果我们有一个像本例中那样带有 constexpr 的模板会发生什么。

template <typename T>
constexpr T get_sum(T a, T b)
{
    return a+b;
}

int main()
{
    constexpr int a = get_sum(2,3); // compile time?
    const float b = get_sum(2.2,3.2); // compile time?
    float c = get_sum(2.2,3.2); // run time?
}

【问题讨论】:

    标签: c++ templates constexpr


    【解决方案1】:

    您的get_sum 是一个函数模板。 get_sum&lt;int&gt; 是一个几乎与任何其他函数一样的函数。不要对模板参数推导感到困惑,这确实发生在编译时。不扣除您的main 与以下内容完全相同:

    constexpr int a=get_sum<int>(2,3);
    const float b=get_sum<double>(2.2,3.2);
    float c=get_sum<double>(2.2,3.2);
    

    简而言之,模板会在需要时由编译器实例化。一旦编译器合成了一个函数,例如get_sum&lt;int&gt;,这是一个和其他函数一样的函数,并且该函数是否为constexpr与它是否是实例化模板的结果是正交的。

    函数上的

    constexpr 告诉编译器该函数可以在编译时进行评估。当在 constexpr 上下文中调用时,编译器必须在编译时对其进行评估。例如constexpr int a 在编译时初始化。 const float 可能已经被编译器初始化。即使是(非常量)float 也可能被编译器完全优化掉。只要程序的可观察行为相同(实际上没有使用您的 3 个变量),就没有什么可以阻止编译器优化某些东西。

    Ergo:
    
    int main()
    {
        constexpr int a=get_sum(2,3);    // get_sum<int> must be called at compile time
        const float b=get_sum(2.2,3.2);  // get_sum<double> is likely to be called at compile time
        float c=get_sum(2.2,3.2);        // get_sum<double> might be called at compile time or runtime
                                         // or not at all, because the call does not 
                                         // contribute to observable behavior
    }
    

    TL;DR

    函数是否为函数模板的实例化与函数是否为constexpr是正交的。

    【讨论】:

      【解决方案2】:

      对于 constexpr,还有 static_assert。 constexpr 可以在编译时和运行时使用。 (C++20 有 consteval,只允许编译时求值)。

      #include <cassert>
      
      template<typename type_t>
      constexpr auto sum(const type_t& value1, const type_t& value2)
      {
          return value1 + value2;
      }
      
      int main()
      {
          constexpr auto constexpr_value = sum(1, 2); // <== compile time
          static_assert(constexpr_value == 3); // <== compile time validation
      
          // or shorter
          static_assert(sum(1, 2) == 3); // <== compile time evaluation
      
          // constexpr's also can compile to runtime versions
          
          auto value = sum(2, 3); // <== runtime evaluation
          assert(value == 5);
      
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 2013-11-18
        • 1970-01-01
        • 2012-08-27
        • 1970-01-01
        • 2013-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-23
        相关资源
        最近更新 更多