Ich verwende c ++ 17 mit Boost.hana, um einige Metaprogrammierprogramme zu schreiben. Ein Problem, das mir aufgefallen ist, ist, welche Art von Ausdruck in einem constexpr-Kontext wie static_assert verwendet werden kann. Hier ist ein Beispiel:
#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);
}
}
Zuerst schreibe ich eine Klasse X mit einem Felddaten und einem Accessor getData () . In der main () ‚s test1 Teil, x1.data und x1.getData () verhalten sich gleich wie ich erwartet hatte. Aber im Test2- Teil static_assert(x2.data[0_c] == 1_c)
verhält sich das Ändern des Arguments in ein Boost :: Hanas-Tupel immer noch gut, static_assert(x2.getData()[0_c] == 1_c)
schlägt jedoch bei der Kompilierung fehl, wobei der Fehler ' Lesen der Nicht-Constexpr-Variablen' x2 'in einem konstanten Ausdruck nicht zulässig ist '. Was weired ist , wenn ich aufgeteilt x2.getData()[0_c]
in auto data = x2.getData();
und static_assert(data[0_c] == 1_c);
kompiliert es wieder gut. Ich würde erwarten, dass sie sich gleich verhalten. Kann jemand helfen zu erklären, warum x2.getData()[0_c]
in static_assert in diesem Beispiel nicht verwendet werden kann?
Zum Reproduzieren: clang ++ 8.0 -I / path / to / hana-1.5.0 / include -std = c ++ 17 Test.cpp