Eu estou usando c ++ 17 com Boost.hana para escrever alguns programas de meta-programação. Uma questão que me surpreendeu é que tipo de expressão pode ser usada em um contexto constexpr como static_assert. Aqui está um exemplo:
#include <boost/hana.hpp>
using namespace boost::hana::literals;
template <typename T>
class X {
public:
T data;
constexpr explicit X(T x) : data(x) {}
constexpr T getData() {
return data;
}
};
int main() {
{ // test1
auto x1 = X(1_c);
static_assert(x1.data == 1_c);
static_assert(x1.getData() == 1_c);
}
{ //test2.1
auto x2 = X(boost::hana::make_tuple(1_c, 2_c));
static_assert(x2.data[0_c] == 1_c);
// static_assert(x2.getData()[0_c] == 1_c); // read of non-constexpr variable 'x2' is not allowed in a constant expression
}
{ //test2.2
auto x2 = X(boost::hana::make_tuple(1_c, 2_c));
auto data = x2.getData();
static_assert(data[0_c] == 1_c);
}
}
Primeiro, escrevo uma classe X com dados de campo e um acessador getData () . No main () 's test1 parte, x1.data e x1.getData () se comportam mesmo que eu esperava. Mas na parte test2 , alterar o argumento para uma tupla boost :: hana static_assert(x2.data[0_c] == 1_c)
ainda se comporta bem, mas static_assert(x2.getData()[0_c] == 1_c)
falha na compilação, com o erro de ' leitura da variável não constexpr' x2 'não é permitido em uma expressão constante '. O que weired é se eu dividir x2.getData()[0_c]
em auto data = x2.getData();
e static_assert(data[0_c] == 1_c);
ele compila bem novamente. Eu esperava que eles se comportassem da mesma maneira. Então, alguém pode ajudar a explicar por x2.getData()[0_c]
que não pode ser usado em static_assert neste exemplo?
Para reproduzir: clang ++ 8.0 -I / caminho / para / hana-1.5.0 / include -std = c ++ 17 Test.cpp