【问题标题】:Can C++ compilers cache the result of constexpr functions?C++ 编译器可以缓存 constexpr 函数的结果吗?
【发布时间】:2017-04-01 21:42:12
【问题描述】:

免责声明:这个问题有点复杂,因为它是几个问题合而为一,但它们都与同一类概念/问题有关。

前提: consexpr 函数只能包含一个 return 语句。

它们可以调用其他函数并使用条件,但理论上它们应该展示功能纯度,因此结果应该可以在某种映射中(由编译器在编译时)缓存,这样编译器就不必不断地重新评估相同的功能。

问题: 这个假设是正确的,还是我没有考虑到无法缓存constexpr 函数的结果? 如果不是,这是否意味着 constexpr 函数每次使用时都必须计算?

templates 呢? templates 上的 constexpr 值是否可以缓存,还是每次都必须重新计算?

【问题讨论】:

  • consexpr 函数通常可以在编译时进行评估;这就是练习的重点。在这种情况下,可执行代码最终只包含作为评估函数调用结果的常量,而不是函数本身的代码。那是终极缓存。或者您是在问编译器是否可以在编译时优化多个评估?可能,但我不确定你为什么会在意。
  • 你为什么要关心?它对您的程序有什么影响?
  • @n.m.不允许 SO 用户仅基于兴趣提出问题吗?问题的根源是否总是存在一些切实的生产问题?
  • constexpr 函数不需要是纯函数。只要求函数至少有一组参数,可以在编译时对其进行评估(即使这样,也不需要诊断)。除其他外,constexpr 函数可以引发异常。请参阅en.cppreference.com/w/cpp/language/constexpr,在示例中查找constexpr char operator[]
  • 简短回答:当然。真实答案:On stateful constexpr functions.

标签: c++ c++11 templates constexpr


【解决方案1】:

我不认为 constexpr 函数必须是纯函数 - 至少,不是所有可能的参数。考虑:

#include <iostream>
#include <stdlib.h>

constexpr int f(int n) { return n == 0 ? 42 : rand(); }

template <int n> void g() {}

int main()
{
    g<f(0)>();  // OK
//    g<f(1)>();  // error
    std::cout << f(0) << ' ' << f(1) << ' ' << f(2);
}

输出:42 1804289383 846930886Demo

【讨论】:

  • 这是一些非常奇怪的行为。我很确定rand 不是constexpr 所以我觉得很奇怪constexpr 函数会接受它为有效。
  • @Pharap 绝对没有要求 constexpr 函数只包含对其他 constexpr 函数的调用。
猜你喜欢
  • 1970-01-01
  • 2016-12-15
  • 1970-01-01
  • 1970-01-01
  • 2011-06-19
  • 2018-10-04
  • 2012-12-22
  • 2020-04-24
相关资源
最近更新 更多