可以是constexpr吗?

时间:2019-11-20 19:39:21

标签: c++ constexpr c++20

所有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类型,因为似乎构造函数在必须初始化指针或引用时永远无法在编译时求值吗?

1 个答案:

答案 0 :(得分: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