The following code compiles and runs in gcc 4.9.1 and clang-3.6 when using -std=c++11:
struct Bar
{
int x;
};
struct Foo
{
static constexpr Bar bars[] = {1, 2, 3};
};
constexpr Bar Foo::bars[];
However, it fails in gcc 4.8.3, resulting in the error message
./cpptest.cpp:14:43: error: could not convert '1' from 'int' to 'const Bar'
static constexpr Bar bars[] = {1, 2, 3};
^
./cpptest.cpp:14:43: error: could not convert '2' from 'int' to 'const Bar'
./cpptest.cpp:14:43: error: could not convert '3' from 'int' to 'const Bar'
Incidentally, if I do the same thing but make bars
a static const global array, it compiles fine in gcc 4.8 and clang. It will also compile just fine if I surround each of the integer literals in the list with an extra pair of {}
.
So is this a bug in gcc 4.8? What does the standard say is the appropriate syntax for this? What part of the c++11 uniform initialization standard is being invoked when I omit the extra braces?
Edit: It looks like the standard says that this should invoke aggregate initialization, which should allow for "brace elision". So it seems it's a bug in gcc 4.8, that was fixed by gcc 4.9, but I'm not at all confident in my reading of the standard. I also can't seem to find any bug report in gcc's bug tracker regarding this, so I could easily be wrong.
In order to do what you want to do, you need specify a constexpr constructor inside Foo:
struct Bar
{
constexpr Bar(int c) : x(c)
{}
int x;
};
struct Foo
{
static constexpr Bar bars[] = {1, 2, 3};
};
constexpr Bar Foo::bars[];
Apparently gcc 4.8.3 doesn't implicity convert the values inside the curly brackets to Bar objects, while gcc 4.9.1 does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With