boostorg / core

Boost Core Utilities
133 stars 83 forks source link

reference_wrapper<T> should convert to reference_wrapper<U> when T& is convertible to U& #83

Closed apolukhin closed 3 years ago

apolukhin commented 3 years ago

This is an issue from trac https://svn.boost.org/trac10/ticket/1112

The following code shows a case that works well with std::reference_wrapper, but fails with boost;:reference_wrapper

#include <iostream>
#include <boost/variant.hpp>

class base {
public :
     virtual void print() const {
         std::cout << "base\n";
     }
};
class child : public base {
public :
     void print() const {
         std::cout << "child\n";
     }
};

class my_visitor{
public:
     void operator()(base& b) const
     {
         b.print();
     }

     void operator()(int i) const
     {
         std::cout << "int\n";
     }
};

#include <boost/ref.hpp>

int main()
{
     child c;

#if 1 // CHANGE ME
    using std::ref;
    using std::reference_wrapper;
#else
    using boost::ref;
    using boost::reference_wrapper;
#endif
     typedef boost::variant<reference_wrapper<base>, int> var_t;
     var_t v = ref(c);

     boost::apply_visitor( my_visitor(), v ); //prints "child"

     base b;
     v = ref(b);
     boost::apply_visitor( my_visitor(), v ); //prints "base"

     std::cin.get();
     return 0;
} 

Godbolt playground: https://godbolt.org/z/bTWrz3

pdimov commented 3 years ago

Should be fixed on develop.

pdimov commented 3 years ago

Merged to master.