将其返回值保存在lambda函数中时,std :: ranges :: sort不能用作“ constexpr”函数

问题描述

此函数f可以将C ++ 20范围算法对象作为参数,然后使用它:

constexpr auto f(auto algo) {
  return [=] {
    algo(std::array{1,0});
    return true;
  }();
}

它可以与std::ranges::sort一起正常工作:

static_assert(f(std::ranges::sort));

但是当我将algo的返回值保存在lambda中时:

constexpr auto f(auto algo) {
  return [=] {
    auto it = algo(std::array{1,0});
    return true;
  }();
}

GCC rejects and says:

<source>:10:16: error: non-constant condition for static assertion
   10 | static_assert(f(std::ranges::sort));
      |               ~^~~~~~~~~~~~~~~~~~~
<source>:10:16: error: 'constexpr auto f(auto:16) [with auto:16 = std::ranges::__sort_fn]' called in a constant expression
<source>:3:16: note: 'constexpr auto f(auto:16) [with auto:16 = std::ranges::__sort_fn]' is not usable as a 'constexpr' function because:
    3 | constexpr auto f(auto algo) {
      |                ^
<source>:7:4: error: call to non-'constexpr' function 'f<std::ranges::__sort_fn>::<lambda()>'
    4 |   return [=] {
      |          ~~~~~
    5 |     auto it = algo(std::array{1,0});
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    6 |     return true;
      |     ~~~~~~~~~~~~
    7 |   }();
      |   ~^~
<source>:4:10: note: 'f<std::ranges::__sort_fn>::<lambda()>' is not usable as a 'constexpr' function because:
    4 |   return [=] {
      |          ^

当我尝试保存constexpr的返回值时,为什么此函数变为非'algo'吗? 还是仅仅是个错误

更新:以下代码为accepted by GCC,因此这很可能是一个错误,我已经提交了bug report.

constexpr auto f(auto algo,auto... args) {
  return [=] () mutable {
    auto it = algo(args...);
    return true;
  }();
}

// those are ok
static_assert(f(std::ranges::reverse,std::array{0})); 
static_assert(f(std::ranges::fill,std::array{0},0));
// those are not ok
// static_assert(f(std::ranges::sort,std::array{0}));    
// static_assert(f(std::ranges::replace,0)); 
// static_assert(f(std::ranges::unique,std::array{0}));
// static_assert(f(std::ranges::next_permutation,std::array{0}));
// static_assert(f(std::ranges::prev_permutation,std::array{0}));

解决方法

如果我声明迭代器为constexpr,那么它对我有用:

constexpr auto it = algo(std::array{1,0});

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...