I want to define constexpr values of a derived type (SBar), using a constructor whose only argument is a variable of the base class (SFoo), which is simply used initialize the base.
This works fine when the base class has no array member. However, when I add an array the derived values can no longer be constexpr. A simple copy of the base class does yield constexpr results, though.
I have explicitly defaulted all copy and move constructors just to be safe.
test.cpp
#define USE_ARRAY
struct SFoo
{
constexpr SFoo() =default;
constexpr SFoo(SFoo const&) =default;
constexpr SFoo(SFoo &) =default;
constexpr SFoo(SFoo &&) =default;
constexpr SFoo& operator = (SFoo const&) =default;
constexpr SFoo& operator = (SFoo &) =default;
constexpr SFoo& operator = (SFoo &&) =default;
# ifdef USE_ARRAY
constexpr SFoo(int const (&array)[1]) :
M_array{array[0]}
{}
int M_array[1] = {0};
# else
constexpr SFoo(int value) :
M_value{value}
{}
int M_value = 0;
# endif
};
struct SBar : SFoo
{
constexpr SBar() =default;
constexpr SBar(SBar const&) =default;
constexpr SBar(SBar &) =default;
constexpr SBar(SBar &&) =default;
constexpr SBar& operator = (SBar const&) =default;
constexpr SBar& operator = (SBar &) =default;
constexpr SBar& operator = (SBar &&) =default;
constexpr SBar(SFoo foo) : SFoo(foo) {}
};
// Instances:
# ifdef USE_ARRAY
constexpr int arg[1] = {3};
# else
constexpr int arg = 3;
# endif
constexpr SFoo foo(arg); // base "value" constructor is constexpr.
constexpr SFoo foo2(foo); // base copy constructor is constexpr.
constexpr SBar bar(foo); // (line 54): this line fails.
compiling with
clang++ -std=c++1z -c -o test.o test.cpp
yields
test.cpp:54:16: error: constexpr variable 'bar' must be initialized by a constant expression
constexpr SBar bar(foo);
^~~~~~~~
1 error generated.
however, everything works if I don't define USE_ARRAY.
Does anyone know why this is happening?
(I know std::array can help, but I'd rather use native arrays and understand the underlying problem).