What is the use of a constexpr on a non-const member function?

懵懂的女人 提交于 2019-12-01 02:35:16

Question: how do you create a constexpr array of size 1024 with all elements set to 0 except element element 42 which needs to be 11?

#include <array>

constexpr auto make_my_array() -> std::array<int, 1024>
{
    std::array<int, 1024> a{};
    a[42] = 11; // std::array::operator[] is constexpr non-const method since C++17

    return a;
}

auto test()
{
    constexpr std::array<int, 1024> a = make_my_array();
}

Or a better yet suggestion from @michael-anderson a make_iota_array:

template <std::size_t N>
constexpr auto make_iota_array() -> std::array<int, N>
{
    std::array<int, N> a{};

    for (std::size_t i = 0; i < N; ++i)
        a[i] = i;

    return a;
}

constexpr means "can be used where a constant expression is required". The "implied const" for declared objects doesn't mean we can't have non-const objects in other contexts. For instance, a somewhat contrived example, created from your own:

template<int>
struct foo {
};

struct A {
    int i = 0;
    constexpr A() {}
    constexpr int a() { return i; }
    constexpr int b() const {return 12; }
    constexpr A&  c() { ++i; return *this; }
};

int main()
{
    foo<A{}.c().a()> f1;
}

Obviously the template argument must be a constant expression. Now, A{} is a prvalue of a literal type with a constexpr c'tor, and it's a non-const object. The member function is allowed to modify this "constant" because the entire computation can collapse to a constant expression at compile time. That's the rationale for the rules, on one foot.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!