I'm using c++17 with Boost.hana to write some meta-programming programs. One issue stuck me is what kind of expression can be used in a constexpr context like static_assert. Here is an example:
#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);
}
}
First I write a class X with a field data and an accessor getData(). In the main()'s test1 part, x1.data and x1.getData() behave same as I expected. But in the test2 part, changing the argument to a boost::hana's tuple, static_assert(x2.data[0_c] == 1_c)
still behaves fine but static_assert(x2.getData()[0_c] == 1_c)
fails compilation, with error of 'read of non-constexpr variable 'x2' is not allowed in a constant expression'. What weired is if I split x2.getData()[0_c]
into auto data = x2.getData();
and static_assert(data[0_c] == 1_c);
it compiles fine again. I'd expect they behave the same. So can anyone help explain why x2.getData()[0_c]
can not be used in static_assert in this example?
To reproduce: clang++8.0 -I/path/to/hana-1.5.0/include -std=c++17 Test.cpp
constexpr
is missing onx2
anddata
,const
ongetData
. godbolt.org/z/ZNL2BK – Jamey