【问题标题】:non-'constexpr' function std::to_string(int) in a consteval lambdaconsteval lambda 中的非“constexpr”函数 std::to_string(int)
【发布时间】:2022-01-16 12:33:03
【问题描述】:

我在以下 lambda 函数中遇到std::to_string() 问题:

#include <iostream>
#include <string>


inline constexpr int a_global_constant { 12345 };


int main( )
{
    auto calculateMsgLength = [ ] ( ) consteval -> std::size_t
    {
        std::string str1 { "Part 1 " };
        std::string str2 { "Part 2 " };
        std::string msg { str1 + str2 /*+ std::to_string( a_global_constant )*/ };

        // The complete message should look like this: Part 1 Part 2 12345

        return msg.length( );
    };

    constexpr std::size_t msgLength { calculateMsgLength( ) };

    std::cout << "Message length == " << msgLength << '\n';
}

以上代码无法在我的GCC v11.2上编译,因此我不得不使用GCC (trunk)Compiler Explorer 进行编译。

但是,只需取消注释对 std::to_string() 的调用,它就不会编译:

<source>: In function 'int main()':
<source>:19:61: error: 'main()::<lambda()>' called in a constant expression
   19 |         constexpr std::size_t msgLength { calculateMsgLength( ) };
      |                                           ~~~~~~~~~~~~~~~~~~^~~
<source>:10:35: note: 'main()::<lambda()>' is not usable as a 'constexpr' function because:
   10 |         auto calculateMsgLength = [ ] ( ) consteval -> std::size_t
      |                                   ^
<source>:10:35: error: call to non-'constexpr' function 'std::string std::__cxx11::to_string(int)'
.
.
.

在不久的将来,std::to_string 是否会在 STL 中变为 constexpr?还是我应该寻找另一种方法来做到这一点? std::to_string 的替代品是什么?

【问题讨论】:

  • 可能是relevant answer?
  • @Adrian Mole 是的,可能有用。
  • std::to_stringsprintf 的形式指定。虽然它不必通过sprintf 实际实现,但它很可能至少在主要实现中与其共享内部结构。使 that constexpr 成为标准库和/或编译器供应商的一大痛点。不要指望它很快。

标签: c++ lambda compiler-errors c++20 consteval


【解决方案1】:

std::to_string 是否会在不久的将来某个时候在 STL 中成为 constexpr?还是我应该寻找另一种方法来做到这一点? std::to_string 的替代品是什么?

我不知道std::to_string 的计划,但整数类型的std::to_chars(和std::from_chars)可能在C++23 中通过P2291 的方式是constexpr。不知道为什么不std::to_string,至少对于整数类型。

也就是说,如果您只想在编译时将基数为 10 的整数转换为 std::string,那么这是一个相当容易编写的算法。唯一棘手的部分是处理INT_MIN(因为如果它是负数,你不能仅仅否定这个论点,那会溢出)。但是由于这是一个constexpr函数,如果你弄错了,那就是编译错误,这样更容易把它弄对。

【讨论】:

  • "不确定为什么不是 std::to_string" 可能是因为语言环境问题。
  • @NicolBolas 只是为了浮点数,对吧?
猜你喜欢
  • 2020-12-03
  • 2020-11-02
  • 2021-01-31
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
  • 2021-02-20
  • 1970-01-01
  • 2022-12-21
相关资源
最近更新 更多