0

I am writing a utility class to "unwrap" a std::reference_wrapper, but I'm a bit conflicted as to what this means.

boost::unwrap_reference<T>::type is defined as U (where T is std::reference_wrapper<U>), but this seems counterintuitive. If a reference_wrapper is meant to "wrap" a reference, then I would expect an "unwrapped" reference_wrapper to be a reference.

Admittedly, this question may lead to opinion or conjecture, but is there any reason to prefer U over U& as the unwrapped type (aside from following the model of boost)? Are there any technical reports which detail boost::unwrap_reference that might provide a rationale for boost's model?

monkey0506
  • 2,489
  • 1
  • 21
  • 27

1 Answers1

1

I don't see what difference it makes.

I suppose it's easier to add &-qualifier than to remove it with std::remove_reference?

In fact this is probably the reason: it's far easier to do further type combinations on bare type than dealing with const/volatile/ref qualification at all times. See e.g. this usage:

template<typename Class, typename TypeIn, typename TypeOut>
struct is_cnv<Class, TypeIn, TypeOut, typename enable_if<is_class<Class>, void>::type>
{
    typedef typename ::boost::unwrap_reference<Class>::type class_type;
    typedef void signature_type(TypeIn const&, optional<TypeOut>&);

    BOOST_DECLARE_IS_CALLABLE(is_callable, operator());

    BOOST_STATIC_CONSTANT(bool, value = (is_callable<class_type, signature_type>::value));
};

(that's in convert/detail/is_converter.hpp, one of the few places that actually uses the unwrap_reference trait from boost/core/ref.hpp)

Because we know class_type is not ref-qualified, it's easier to feed it into is_callable and not get surprised.

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Your reasoning does make sense. The way I was using the utility class depended on it returning a reference type, but I can actually just avoid the utility class altogether. – monkey0506 Jan 03 '18 at 03:25