Opened 6 years ago

Last modified 6 years ago

#12423 new Bugs

fusion::make_map breaks when passing references

Reported by: oleg00@… Owned by: Joel de Guzman
Milestone: To Be Determined Component: fusion
Version: Boost 1.61.0 Severity: Problem
Keywords: fusion make_map Cc:

Description

When using variadic maps the following code doesn't compile:

int i = 0;
fusion::make_map<int>(ref(i));

Clang gives this error: error : no matching constructor for initialization of 'detail::map_impl<0, pair<int, int &> >' 1> : base_type(first, rest...) 1> ~

There is a constructor in fusion::pair that can do the required conversion:

       template <typename Second2>
        BOOST_FUSION_GPU_ENABLED
        pair(Second2&& val
          , typename boost::disable_if<is_lvalue_reference<Second2> >::type* /* dummy */ = 0
          , typename boost::enable_if<is_convertible<Second2, Second> >::type* /*dummy*/ = 0
        ) : second(BOOST_FUSION_FWD_ELEM(Second, val)) {}

But it's not being invoked since there's no make_map function that takes rvalue refs. I was able to make this work by adding another make_map overload:

   template <typename ...Key, typename ...T>
    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
      inline map<
      fusion::pair<
      Key
      , typename detail::as_fusion_element<T>::type
      >...>
      make_map(T &&... arg)
    {
      typedef map<
        fusion::pair<
        Key
        , typename detail::as_fusion_element<T>::type
      >...>
        result_type;

      return result_type(std::forward<T>(arg)...);
    }

Change History (1)

comment:1 by Joel de Guzman, 6 years ago

Could you please prepare a PR for this? Thanks!

Note: See TracTickets for help on using tickets.