可以是constexpr吗?


11

所有std :: span的构造函数都声明为constexpr,但是我似乎无法在constexpr上下文中使用它们中的任何一个。取消注释以下任何constexpr都将导致编译错误。

#include <array>
#include <span>

int main()
{
    constexpr int carray[3] = { 0, 1, 2 };
    constexpr std::array<int, 3> array{ 0, 1, 2 };
    using S = std::span<const int, 3>;

    /*constexpr*/ S span1{ array.data(), 3 };
    /*constexpr*/ S span2{array.begin(), array.end()};
    /*constexpr*/ S span3{carray};
    /*constexpr*/ S span4{array};
}

实际上是否可以创建constexpr span类型,因为似乎构造函数在必须初始化指针或引用时永远无法在编译时求值吗?


取消注释constexprs不会删除它们。
安德烈亚斯(Andreas Loanjoe)

您正在初始化运行时跨度,我要初始化一个constexpr跨度
Andreas Loanjoe19年

h 不知道为什么我那样做。没关系
-NathanOliver

很奇怪,看不出为什么跨度仅存在于本地范围内是为什么……
Andreas Loanjoe

Answers:


13

您不能在这样的常量表达式中使用非静态函数局部变量。您需要地址稳定性,而这只能通过静态对象来实现。修改代码为

constexpr std::array<int, 3> array{ 0, 1, 2 };
constexpr int carray[3] = { 0, 1, 2 };

int main()
{
    using S = std::span<const int, 3>;

    constexpr S span1{ array.data(), 3 };
    constexpr S span2{array.begin(), array.end()};
    constexpr S span3{carray};
    constexpr S span4{array};
}

要么

int main()
{
    static constexpr std::array<int, 3> array{ 0, 1, 2 };
    static constexpr int carray[3] = { 0, 1, 2 };
    using S = std::span<const int, 3>;

    constexpr S span1{ array.data(), 3 };
    constexpr S span2{array.begin(), array.end()};
    constexpr S span3{carray};
    constexpr S span4{array};
}

允许您创建一个constexpr std::span


5
范围不是问题。储存期限为。静态本地应该工作。
eerorika

如果全部都是函数中的函数局部对象constexpr(没有explicit static),它也可以工作。这样的对象是否具有默认的静态存储持续时间,或者这有什么不同?
n314159

@ n314159我不确定是否允许这样做,或者您是否陷入了恐惧:如果constexpr函数的任何特殊化都不是核心常量表达式,则该函数的格式不正确,不需要诊断子句。 [expr.const] / 10仅允许使用静态变量。
NathanOliver

@ n314159:我不确定您所说的是什么(或“作品”),但要注意函数中使用某些内容作为常量表达式(constexpr或否)与使用某些内容构造常量之间的区别通过 constexpr函数表达。
戴维斯·鲱鱼

您可能要说的是,非静态(常数)可用于常数表达式,但不能用于其地址
戴维斯·鲱鱼
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.