Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

initializer_list member and constexpr

235 views
Skip to first unread message

Juha Nieminen

unread,
Jul 20, 2016, 5:15:12 AM7/20/16
to
Consider the following code:

//--------------------------------------------------------
#include <initializer_list>

struct A { int x, y; };
struct B { int x, y; std::initializer_list<int> l; };

struct Test
{
A a; B b;
constexpr Test(const A& ia): a(ia), b{0,0,{}} {}
constexpr Test(const B& ib): a{0,0}, b(ib) {}
};

constexpr B kB { 1, 2, { 1, 2, 3 } };
constexpr Test kTest1 = A { 5, 10 };
constexpr Test kTest2 = B { 5, 10, { 1, 2, 3 } };

int main() {}
//--------------------------------------------------------

It compiles with gcc, but not with clang. The latter says:

//--------------------------------------------------------
test.cc:16:16: error: constexpr variable 'kTest2' must be initialized by a
constant expression
constexpr Test kTest2 = B { 5, 10, { 1, 2, 3 } };
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cc:16:16: note: pointer to subobject of temporary is not a constant
expression
test.cc:16:36: note: temporary created here
constexpr Test kTest2 = B { 5, 10, { 1, 2, 3 } };
^
//--------------------------------------------------------

Which one is right?

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

Ian Collins

unread,
Jul 20, 2016, 6:37:41 AM7/20/16
to
I think clang is correct. { 1, 2, 3 } is a temporary initializer_list
object.

constexpr std::initializer_list<int> il { 1, 2, 3 };
constexpr Test kTest2 = B { 5, 10, il };

Should be okay.
--
Ian

Juha Nieminen

unread,
Jul 21, 2016, 10:31:04 AM7/21/16
to
Ian Collins <ian-...@hotmail.com> wrote:
>> constexpr B kB { 1, 2, { 1, 2, 3 } };
>> constexpr Test kTest2 = B { 5, 10, { 1, 2, 3 } };
>
> I think clang is correct. { 1, 2, 3 } is a temporary initializer_list
> object.

If that's so, why doesn't it complain about the kB initialization?

Ian Collins

unread,
Jul 21, 2016, 4:39:55 PM7/21/16
to
On 07/22/16 02:30 AM, Juha Nieminen wrote:
> Ian Collins <ian-...@hotmail.com> wrote:
>>> constexpr B kB { 1, 2, { 1, 2, 3 } };
>>> constexpr Test kTest2 = B { 5, 10, { 1, 2, 3 } };
>>
>> I think clang is correct. { 1, 2, 3 } is a temporary initializer_list
>> object.
>
> If that's so, why doesn't it complain about the kB initialization?

Because there the initialiser list is being directly initialised, not
being passed as a constructor parameter.

--
Ian
0 new messages