diff --git a/include/boost/pfr/core.hpp b/include/boost/pfr/core.hpp index d621f273..a4f230cd 100644 --- a/include/boost/pfr/core.hpp +++ b/include/boost/pfr/core.hpp @@ -255,7 +255,7 @@ constexpr auto structure_tie(T&&, std::enable_if_t< std::is_rvalue_reference constexpr void for_each_field(T&& value, F&& func) { - return ::boost::pfr::detail::for_each_field(std::forward(value), std::forward(func)); + ::boost::pfr::detail::for_each_field(std::forward(value), std::forward(func)); } /// \brief std::tie-like function that allows assigning to tied values from aggregates. diff --git a/include/boost/pfr/detail/core_name20_static.hpp b/include/boost/pfr/detail/core_name20_static.hpp index 4c615904..ba03cac9 100644 --- a/include/boost/pfr/detail/core_name20_static.hpp +++ b/include/boost/pfr/detail/core_name20_static.hpp @@ -245,14 +245,14 @@ template constexpr void for_each_field_with_name(T&& value, F&& func) { return boost::pfr::detail::for_each_field( std::forward(value), - [f = std::forward(func)](auto&& field, auto index) mutable { + [&func](auto&& field, auto index) mutable { using IndexType = decltype(index); using FieldType = decltype(field); constexpr auto name = boost::pfr::detail::get_name, IndexType::value>(); if constexpr (std::is_invocable_v) { - f(name, std::forward(field), index); + std::forward(func)(name, std::forward(field), index); } else { - f(name, std::forward(field)); + std::forward(func)(name, std::forward(field)); } }); } diff --git a/include/boost/pfr/detail/for_each_field.hpp b/include/boost/pfr/detail/for_each_field.hpp index 33b3ec1f..c2d92ed3 100644 --- a/include/boost/pfr/detail/for_each_field.hpp +++ b/include/boost/pfr/detail/for_each_field.hpp @@ -42,14 +42,14 @@ constexpr void for_each_field(T&& value, F&& func) { ::boost::pfr::detail::for_each_field_dispatcher( value, - [f = std::forward(func)](auto&& t) mutable { + [&func](auto&& t) mutable { // MSVC related workaround. Its lambdas do not capture constexprs. constexpr std::size_t fields_count_val_in_lambda = boost::pfr::detail::fields_count>(); ::boost::pfr::detail::for_each_field_impl( t, - std::forward(f), + std::forward(func), detail::make_index_sequence{}, std::is_rvalue_reference{} ); diff --git a/test/core/run/for_each_field.cpp b/test/core/run/for_each_field.cpp index 031636b4..30001145 100644 --- a/test/core/run/for_each_field.cpp +++ b/test/core/run/for_each_field.cpp @@ -56,6 +56,13 @@ struct simple { struct empty{}; +struct stateful_counting_visitor { + std::size_t count = 0; + + template + void operator()(const T&) { ++count; } +}; + #if BOOST_PFR_USE_CPP17 constexpr std::size_t get_field_count_through_for_each_field() { std::size_t counter = 0; @@ -132,6 +139,10 @@ int main () { }); BOOST_TEST_EQ("", ss.str()); ss.str(""); + + stateful_counting_visitor counting_visitor; + boost::pfr::for_each_field(simple{}, counting_visitor); + BOOST_TEST_EQ(3, counting_visitor.count); return boost::report_errors(); } diff --git a/test/core_name/run/for_each_field_with_name.cpp b/test/core_name/run/for_each_field_with_name.cpp index c17d9c19..b071e04e 100644 --- a/test/core_name/run/for_each_field_with_name.cpp +++ b/test/core_name/run/for_each_field_with_name.cpp @@ -15,6 +15,12 @@ struct SimpleStruct { std::string str; }; +struct stateful_counting_visitor { + std::size_t count = 0; + + template + void operator()(std::string_view /*name*/, const T&) { ++count; } +}; int main () { std::map m; @@ -27,5 +33,9 @@ int main () { BOOST_TEST_EQ(m["c"], "e"); BOOST_TEST_EQ(m["str"], "test"); + stateful_counting_visitor counting_visitor; + boost::pfr::for_each_field_with_name(SimpleStruct{}, counting_visitor); + BOOST_TEST_EQ(2, counting_visitor.count); + return boost::report_errors(); }