literal class compile error with constexpr constructor and function (differ vc, g++)中接受的答案表明,在C ++ 14中,constexpr int A::a()
和constexpr A::a() const
的使用方式存在差异。即成员函数上的constexpr
并不意味着该函数不会更改它所作用的对象。
给出的例子是:
struct A {
constexpr A() {}
constexpr int a() {return 12; }
constexpr int b() const {return 12; }
};
int main()
{
constexpr A a;
// DOES NOT COMPILE as a() is not const
// constexpr int j = a.a();
const int k = a.b(); // Fine since b() is const
}
对我而言,constexpr
上的a()
似乎毫无用处。
非constexpr
成员函数的const
是否具体用途?
答案 0 :(得分:13)
constexpr
表示“可用于需要常量表达式的地方”。声明对象的“隐含const”并不意味着我们不能在其他上下文中包含非const对象。例如,一个有点人为的例子,由你自己创建:
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;
}
显然,模板参数必须是常量表达式。现在,A{}
是带有constexpr c'tor的文字类型的prvalue,它是一个非const对象。允许成员函数修改此“常量”,因为整个计算可以在编译时折叠为常量表达式。这是规则的基本原理,一只脚。
答案 1 :(得分:11)
问题:如何创建大小为1024
的constexpr数组,其中所有元素都设置为0
,但元素元素42
除外,需要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();
}
或者来自@ michael-anderson 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;
}