【问题标题】:GCC constexpr lambdas in constexpr functions and evaluation in compile timeconstexpr 函数中的 GCC constexpr lambdas 和编译时的评估
【发布时间】:2015-10-15 21:56:57
【问题描述】:

代码优先,我们有以下代码用于在编译时累积constexpr std::array

template <typename T, std::size_t N, typename O>
constexpr T compile_time_accumulator(const std::array<T, N> const &A, const std::size_t i, const O& op, const T initialValue)
{
  return (i < N)
       ? op(A[i], compile_time_accumulator(A, i + 1, op, initialValue))
       : initialValue;
}

以及以下代码示例来测试/验证它(即,它在编译时评估):

constexpr std::array<int, 4> v {{4, 5, 6, 7}};
std::cout << std::integral_constant<int, compile_time_accumulator(v, 42, std::plus<int>())>::value 
          << std::endl;

LIVE DEMO

现在如果将运算符 std::plus&lt;int&gt; 更改为 constexpr lambda:

constexpr auto lambda_plus = [] (int x, int y) { return x + y; };

并像下面这样调用它:

constexpr std::array<int, 4> v {{4, 5, 6, 7}};
std::cout << std::integral_constant<int, compile_time_accumulator(v, 42, lambda_plus)>::value << std::endl;
                                                                         ^^^^^^^^^^^ 

我得到一个错误,那个 lambda 不是 constexpr

调用非 constexpr 函数 ''

现在做了一点research 我发现constexpr lambdas 还不支持。

问:

为什么如果不支持constexpr lambda,我们可以首先定义constexpr lambda?

编辑:

clang 似乎不接受code。那么哪个编译器是对的呢?

【问题讨论】:

  • @NorahAttkins 我已经包含了该参考资料。
  • 那么你已经有了分析器(@Columbo 也在说同样的事情)
  • @NorahAttkins 哎呀,我现在才意识到这一点。好吧,看起来肯定是个骗子。
  • @NorahAttkins 这不是骗局。我知道constexpr lambdas 是不允许的。我在问为什么 gcc 在示例中接受它们。

标签: c++ c++11 lambda c++14 constexpr


【解决方案1】:

根据 [expr.const]/(2.6),代码确实格式不正确;尽管 corresponding proposal 正在流通,但常量表达式中还不允许使用 lambda。 GCC 接受lambda_plus 的声明是不正确的。

【讨论】:

  • 是的,看来你是对的,clang 抱怨他们code
【解决方案2】:

C++11 允许对 constexpr 的定义数量非常有限,而 C++14 有很长的列表不是 constexpr

来自 n4296(C++14 的候选版本)5.20.2.6

5.20 常量表达式 [expr.const]

2 条件表达式 e 是核心常量表达式,除非 e 的评估,遵循抽象机 (1.9) 的规则, 将评估以下表达式之一:

2.6) — 一个 lambda 表达式 (5.1.2);

所以答案是 lambda 不行,所以编译器一定是错的。

【讨论】:

  • 是的,看来你是对的,clang 抱怨他们code
  • @101010 你好(再次;)),你会注意到if you compile with -std=c++11,gcc 和 clang 都不允许std::plus()...也许 constexprnessstd::plus::operator() 的 /i> 仅在 C++14 之后添加(我没有检查标准,但 cppreferencecplusplus.com 似乎没有提供类似的信息)
猜你喜欢
  • 1970-01-01
  • 2021-02-13
  • 2012-12-24
  • 2014-04-06
  • 2017-07-03
  • 2020-10-01
  • 2017-05-26
  • 2022-11-18
  • 1970-01-01
相关资源
最近更新 更多