make_array and brace-init list. Should this be a defect or I am wrong...?

85 views
Skip to first unread message

Germán Diago

unread,
Aug 19, 2016, 8:17:42 AM8/19/16
to ISO C++ Standard - Future Proposals
Hello everyone,

I am trying to implement a custom version of (except for common-type) of make_array.

I see a problem when implementing, let me drive it by example. This is my question in stackoverflow:


So I can do this:

make_array<int>(1, 2, 3, 4, 5.5); 

But not this:

make_array<int>({1}, {2}, {3});

So:

1. I cannot prevent narrowing conversions.
2. I cannot construct my own types from brace-init lists in template contexts *even if I provide an explicit type argument*.

I think that should just work, look at my implementation. Are there any workarounds to this?






Germán Diago

unread,
Aug 19, 2016, 8:26:08 AM8/19/16
to ISO C++ Standard - Future Proposals
I think the root of the problem is this one:

" A brace enclosed initializer list is not an expression and doesn't have type and therefore cannot be deduced by the template."

Germán Diago

unread,
Aug 19, 2016, 8:32:47 AM8/19/16
to ISO C++ Standard - Future Proposals
Ok, I see I could use an initializer_list<Val> for the argument instead of variadic Val...

So my conclusion here is at least that make_array should do the same when receiving explicit parameter for value_type?

One minor annoyance to this is that we need an extra {} before the arguments, but still can live with that I guess.

S.B.

unread,
Aug 19, 2016, 11:58:15 AM8/19/16
to ISO C++ Standard - Future Proposals
I don't think it's possible to enable `make_array<int>({1}, {2}, {3})` by only changing the implementation of `make_array`. However, it's possible to add another overload of `to_array` to enable `to_array<int>({ {1}, {2}, {3} })`. After all, `to_array<const int>({ {1}, {2}, {3} })` is already valid (and returns a std::array<int,3>) using std::experimental::fundamentals_v2::to_array.
See also https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/GS3j9tcXnI0

Zhihao Yuan

unread,
Aug 19, 2016, 12:31:44 PM8/19/16
to std-pr...@isocpp.org
On Fri, Aug 19, 2016 at 10:58 AM, S.B.
<i.and.my.li...@gmail.com> wrote:
> However, it's possible to add another overload of `to_array` to enable
> `to_array<int>({ {1}, {2}, {3} })`.

Not possible, because initializer_list's size() is a part
of value, which will not affect std::array's size which
is a part of type.

> After all, `to_array<const int>({ {1},
> {2}, {3} })` is already valid (and returns a std::array<int,3>) using
> std::experimental::fundamentals_v2::to_array.

Not valid.

There is a way to support braced-init. First extend
to_array with rvalue reference, then combine this
with compound literals in C:

auto a7 = to_array((std::pair<int, float>[])
{ { 3, .0f }, { 4, .1f }, { 4, .1e23f } });

Implemented,

https://gist.github.com/lichray/6034753#file-make_array-cc-L169

Tested against gcc and clang.

After all it's non-standard.

--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
___________________________________________________
4BSD -- http://blog.miator.net/

S.B.

unread,
Aug 19, 2016, 12:52:58 PM8/19/16
to ISO C++ Standard - Future Proposals

S.B.

unread,
Aug 19, 2016, 1:15:44 PM8/19/16
to ISO C++ Standard - Future Proposals


On Saturday, August 20, 2016 at 12:31:44 AM UTC+8, Zhihao Yuan wrote:

Zhihao Yuan

unread,
Aug 19, 2016, 2:48:46 PM8/19/16
to std-pr...@isocpp.org
On Fri, Aug 19, 2016 at 12:15 PM, S.B.
<i.and.my.li...@gmail.com> wrote:
> I think it's CWG 1591 (Deducing array bound and element type from
> initializer list) that makes this use valid.

Interesting. And the rvalue reference overload is really
demanded right now, to enable

to_array<std::unique_ptr<int>>({ std::make_unique<int>(3) })
Reply all
Reply to author
Forward
0 new messages