Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested arrays with C++ 17. #16

Closed
kyku opened this issue Nov 16, 2017 · 2 comments
Closed

Nested arrays with C++ 17. #16

kyku opened this issue Nov 16, 2017 · 2 comments

Comments

@kyku
Copy link

kyku commented Nov 16, 2017

The following snippet compiles fine in C++14 mode but fails in C++17:

#include <boost/pfr/precise/core.hpp>

int main()
{
  struct foo
  {
    int things[3];
  };
  
  boost::pfr::for_each_field(foo{{1, 2, 3}}, [&](auto& field) {});
}

Tested on GCC 7.2.0 and CLANG 5.0.0.

Errors from CLANG:

In file included from main.cpp:5:
In file included from include/boost/pfr/precise/core.hpp:21:
In file included from include/boost/pfr/detail/core17.hpp:10:
include/boost/pfr/detail/core17_generated.hpp:57:9: error: type 'foo' decomposes into 1 elements, but 3 names were provided
auto& [a,b,c] = val;
^
include/boost/pfr/detail/core17_generated.hpp:1032:30: note: in instantiation of function template specialization 'boost::pfr::detail::tie_as_tuple'
requested here
return boost::pfr::detail::tie_as_tuple(val, fields_count_tag{});
^
include/boost/pfr/detail/core17.hpp:52:17: note: in instantiation of function template specialization 'boost::pfr::detail::tie_as_tuple' requested here
detail::tie_as_tuple(t)
^
include/boost/pfr/precise/core.hpp:145:27: note: in instantiation of function template specialization 'boost::pfr::detail::for_each_field_dispatcher<foo,
(lambda at include/boost/pfr/precise/core.hpp:147:9), 0, 1, 2>' requested here
::boost::pfr::detail::for_each_field_dispatcher(
^
main.cpp:102:15: note: in instantiation of function template specialization 'boost::pfr::for_each_field<foo, (lambda at main.cpp:102:46)>' requested here
boost::pfr::for_each_field(foo{{1, 2, 3}}, [&](auto& field) {});
^
1 error generated.

Errors from GCC:

In file included from include/boost/pfr/detail/core17.hpp:10:0,
from include/boost/pfr/precise/core.hpp:21,
from main.cpp:5:
include/boost/pfr/detail/core17_generated.hpp: In instantiation of ‘constexpr auto boost::pfr::detail::tie_as_tuple(T&, boost::pfr::detail::size_t_<3>) [with T = main()::foo; boost::pfr::detail::size_t_<3> = std::integral_constant<long unsigned int, 3>]’:
include/boost/pfr/detail/core17_generated.hpp:1032:42: required from ‘constexpr auto boost::pfr::detail::tie_as_tuple(T&) [with T = main()::foo]’
include/boost/pfr/detail/core17.hpp:52:29: required from ‘void boost::pfr::detail::for_each_field_dispatcher(T&, F&&, std::index_sequence<_Idx ...>) [with T = main()::foo; F = boost::pfr::for_each_field(T&&, F&&) [with T = main()::foo; F = main()::<lambda(auto:6&)>]::<lambda(auto:1&&)>; long unsigned int ...I = {0, 1, 2}; std::index_sequence<_Idx ...> = std::integer_sequence<long unsigned int, 0, 1, 2>]’
include/boost/pfr/precise/core.hpp:145:52: required from ‘void boost::pfr::for_each_field(T&&, F&&) [with T = main()::foo; F = main()::<lambda(auto:6&)>]’
main.cpp:102:65: required from here
include/boost/pfr/detail/core17_generated.hpp:57:9: error: 3 names provided while ‘main()::foo’ decomposes into 1 elements
auto& [a,b,c] = val;
^~~~~~~
In file included from include/boost/pfr/precise/core.hpp:21:0,
from main.cpp:5:
include/boost/pfr/detail/core17.hpp: In instantiation of ‘void boost::pfr::detail::for_each_field_dispatcher(T&, F&&, std::index_sequence<_Idx ...>) [with T = main()::foo; F = boost::pfr::for_each_field(T&&, F&&) [with T = main()::foo; F = main()::<lambda(auto:6&)>]::<lambda(auto:1&&)>; long unsigned int ...I = {0, 1, 2}; std::index_sequence<_Idx ...> = std::integer_sequence<long unsigned int, 0, 1, 2>]’:
include/boost/pfr/precise/core.hpp:145:52: required from ‘void boost::pfr::for_each_field(T&&, F&&) [with T = main()::foo; F = main()::<lambda(auto:6&)>]’
main.cpp:102:65: required from here
include/boost/pfr/detail/core17.hpp:51:23: error: invalid use of void expression
std::forward(f)(
~~~~~~~~~~~~~~~~~~^
detail::tie_as_tuple(t)
~~~~~~~~~~~~~~~~~~~~~~~
);
~

@apolukhin
Copy link
Member

That's a known issue and it is documented (for example here)

If you know some way to workaround that issue or to static_assert it, then please give me hint.

@kyku kyku closed this as completed Nov 27, 2017
@kasper93
Copy link

kasper93 commented Dec 24, 2017

@apolukhin: You could test explicit initialization of every member instead one aggregate list.

Let's consider this example:

struct Foo
{
    int a;
    int b[3];
    int c;
};

You can construct it like so

Foo foo{1, 1, 1, 1, 1};

which will of course give you "flat" number, brace elision is coming into play. But if you instead do this:

Foo foo{{}, {}, {}};

you will get "precise" number of members. Because as you probably figured this will fail:

Foo foo{{}, {}, {}, {}};

I can make PR in new year (should have time then to test it properly ;p) with the changes to support precise mode with nested arrays. Unless you beat me to it :>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants