以下代码无法编译
#include <array>
#include <iostream>
#include <utility>
template <std::size_t N>
class A {
template <std::size_t... Ints>
static constexpr void get_phi_base_impl(std::array<std::array<double, N>, N>& res, std::index_sequence<Ints...>)
{ ( (std::get<Ints>(res).fill(0), std::get<Ints>(std::get<Ints>(res)) = 1), ...); }
public:
static constexpr std::array<std::array<double, N>, N> get_phi_base();
static constexpr std::array<std::array<double, N>, N> base = get_phi_base();
};
template <std::size_t N>
constexpr std::array<std::array<double, N>, N> A<N>::get_phi_base()
{
std::array<std::array<double, N>, N> res;
get_phi_base_impl(res, std::make_index_sequence<N>{});
return res;
}
int main()
{
A<4> a;
for (const auto& el : a.base)
{
for (const auto& x : el)
std::cout << x << ' ';
std::cout << std::endl;
}
return 0;
}
检查一下Live on Coliru。
g++给予了一个相当隐晦错误
main.cpp:13:76: error: 'static constexpr std::array<std::array<double, N>, N> A<N>::get_phi_base() [with long unsigned int N = 4]' called in a constant expression
13 | static constexpr std::array<std::array<double, N>, N> base = get_phi_base();
| ~~~~~~~~~~~~^~
main.cpp:17:48: note: 'static constexpr std::array<std::array<double, N>, N> A<N>::get_phi_base() [with long unsigned int N = 4]' is not usable as a 'constexpr' function because:
17 | constexpr std::array<std::array<double, N>, N> A<N>::get_phi_base()
| ^~~~
clang++给出一个更容易理解的错误
test.cpp:13:57: error: constexpr variable 'base' must be initialized by a constant expression
static constexpr std::array<std::array<double, N>, N> base = get_phi_base();
^ ~~~~~~~~~~~~~~
test.cpp:27:27: note: in instantiation of static data member 'A<4>::base' requested here
for (const auto& el : a.base)
^
test.cpp:19:40: note: non-constexpr constructor 'array' cannot be used in a constant expression
std::array<std::array<double, N>, N> res;
^
test.cpp:13:64: note: in call to 'get_phi_base()'
static constexpr std::array<std::array<double, N>, N> base = get_phi_base();
奇怪的是,如果我删除main()中的打印部分
//for (const auto& el : a.base)
// {
// for (const auto& x : el)
// std::cout << x << ' ';
// std::cout << std::endl;
// }
两个编译器都不再抱怨了。启用警告后,我只得到一个未使用变量a的警告。我正在用-std=c++17 -Wall -pedantic
编译。
有没有办法把constexpr
构造成std::array
的std::array
?为什么如果我省略了打印,错误就会消失?
我主要对c++17
的答案感兴趣。
this question的答案解释了为什么上面的代码在C20中编译,而不是在C17中编译。但是,它没有回答constexpr
的具体问题-填充std::array<std::array<T, N>, N>
。特别是,answer中给出的初始化res{};
没有解决这个问题(出现另一个编译错误)。
1条答案
按热度按时间2skhul331#
在C17中,constexpr函数不能包含“未执行初始化的变量的定义”。
在C20中已删除此限制。
在C++17中,你可以这样创建二维数组(我假设它是一个单位矩阵):
Demo
当然,这些函数在
A
中可以是静态的。