reference_wrapper doesn't seem to be functioning correctly with pointers to
member functions.  I'm attaching my test case below.  Note that the actual
wording of the  TR is somewhat garbled in this case: but it's covered by
TR.DR.10.41.

Regards, John Maddock.

The test case:

#include <tr1/functional>

#include <boost/static_assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include "verify_return.hpp"

struct test_type
{
   int member();
   int cmember()const;
   int member2(char);
   int cmember2(char)const;
};

struct functor1 : public std::unary_function<int, double>
{
   double operator()(int)const;
};

struct functor2 : public std::binary_function<int, char, double>
{
   double operator()(int, char)const;
};

int main()
{
   BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::unary_function<int,
double>, std::tr1::reference_wrapper<double (int)> >::value));
   BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::unary_function<int,
double>, std::tr1::reference_wrapper<double (*)(int)> >::value));
  
BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::unary_function<test_type*,
int>, std::tr1::reference_wrapper<int (test_type::*)()> >::value));
   BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::unary_function<const
test_type*, int>, std::tr1::reference_wrapper<int (test_type::*)()const>
>::value));
   BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::unary_function<int,
double>, std::tr1::reference_wrapper<functor1> >::value));

   BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::binary_function<int,
char, double>, std::tr1::reference_wrapper<double (int, char)> >::value));
   BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::binary_function<int,
char, double>, std::tr1::reference_wrapper<double (*)(int, char)> >::value));
  
BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::binary_function<test_type*,
char, int>, std::tr1::reference_wrapper<int (test_type::*)(char)> >::value));
   BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::binary_function<const
test_type*, char, int>, std::tr1::reference_wrapper<int
(test_type::*)(char)const> >::value));
   BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::binary_function<int,
char, double>, std::tr1::reference_wrapper<functor2> >::value));

   // now check operator():
   std::tr1::reference_wrapper<double (int)>* pr1;
   verify_return_type((*pr1)(0), double());
   std::tr1::reference_wrapper<double (*)(int)>* pr2;
   verify_return_type((*pr2)(0), double());
   std::tr1::reference_wrapper<int (test_type::*)()>* pr3;
   verify_return_type((*pr3)(0), int());
   std::tr1::reference_wrapper<int (test_type::*)()const>* pr4;
   verify_return_type((*pr4)(0), int());
   std::tr1::reference_wrapper<functor1>* pr5;
   verify_return_type((*pr5)(0), double());

   std::tr1::reference_wrapper<double (int, char)>* pr1b;
   verify_return_type((*pr1b)(0,0), double());
   std::tr1::reference_wrapper<double (*)(int, char)>* pr2b;
   verify_return_type((*pr2b)(0,0), double());
   std::tr1::reference_wrapper<int (test_type::*)(char)>* pr3b;
   verify_return_type((*pr3b)(0,0), int());
   std::tr1::reference_wrapper<int (test_type::*)()const>* pr4b;
   verify_return_type((*pr4b)(0,0), int());
   std::tr1::reference_wrapper<functor1>* pr5b;
   verify_return_type((*pr5b)(0,0), double());
}

The errors occur on invocation of the function objects:

gcc-C++-action
../../../bin/boost/libs/tr1/test/test_reference_wrapper_tricky.test/gcc-4.0.2/debug/test_reference_wrapper_tricky.o
/home/john/boost/libs/tr1/test/test_reference_wrapper_tricky.cpp: In function
`int main()':
/home/john/boost/libs/tr1/test/test_reference_wrapper_tricky.cpp:56: error: no
match for call to `(std::tr1::reference_wrapper<int (test_type::*)()>) (int)'
/usr/local/gcc/4.0.2/lib/gcc/i686-pc-linux-gnu/4.0.2/../../../../include/c++/4.0.2/tr1/ref_wrap_iterate.h:42:
note: candidates are: typename std::tr1::result_of<typename
std::tr1::_Function_to_function_pointer<_Tp,
std::tr1::is_function<_Tp>::value>::type ()()>::type
std::tr1::reference_wrapper<_Tp>::operator()() const [with _Tp = int
(test_type::*)()]
/usr/local/gcc/4.0.2/lib/gcc/i686-pc-linux-gnu/4.0.2/../../../../include/c++/4.0.2/tr1/functional_iterate.h:169:
note:                 typename std::tr1::result_of<typename
std::tr1::reference_wrapper<_Tp>::_M_func_type ()(_T1)>::type
std::tr1::reference_wrapper<_Tp>::operator()(_T1&) const [with _T1 = int, _Tp =
int (test_type::*)()]
/home/john/boost/libs/tr1/test/test_reference_wrapper_tricky.cpp:58: error: no
match for call to `(std::tr1::reference_wrapper<int (test_type::*)()const>)
(int)'
/usr/local/gcc/4.0.2/lib/gcc/i686-pc-linux-gnu/4.0.2/../../../../include/c++/4.0.2/tr1/ref_wrap_iterate.h:42:
note: candidates are: typename std::tr1::result_of<typename
std::tr1::_Function_to_function_pointer<_Tp,
std::tr1::is_function<_Tp>::value>::type ()()>::type
std::tr1::reference_wrapper<_Tp>::operator()() const [with _Tp = int
(test_type::*)()const]
/usr/local/gcc/4.0.2/lib/gcc/i686-pc-linux-gnu/4.0.2/../../../../include/c++/4.0.2/tr1/functional_iterate.h:169:
note:                 typename std::tr1::result_of<typename
std::tr1::reference_wrapper<_Tp>::_M_func_type ()(_T1)>::type
std::tr1::reference_wrapper<_Tp>::operator()(_T1&) const [with _T1 = int, _Tp =
int (test_type::*)()const]
/home/john/boost/libs/tr1/test/test_reference_wrapper_tricky.cpp:60: error: no
match for call to `(std::tr1::reference_wrapper<functor1>) (int)'
/usr/local/gcc/4.0.2/lib/gcc/i686-pc-linux-gnu/4.0.2/../../../../include/c++/4.0.2/tr1/ref_wrap_iterate.h:42:
note: candidates are: typename std::tr1::result_of<typename
std::tr1::_Function_to_function_pointer<_Tp,
std::tr1::is_function<_Tp>::value>::type ()()>::type
std::tr1::reference_wrapper<_Tp>::operator()() const [with _Tp = functor1]
/usr/local/gcc/4.0.2/lib/gcc/i686-pc-linux-gnu/4.0.2/../../../../include/c++/4.0.2/tr1/functional_iterate.h:169:
note:                 typename std::tr1::result_of<typename
std::tr1::reference_wrapper<_Tp>::_M_func_type ()(_T1)>::type
std::tr1::reference_wrapper<_Tp>::operator()(_T1&) const [with _T1 = int, _Tp =
functor1]
/home/john/boost/libs/tr1/test/test_reference_wrapper_tricky.cpp:67: error: no
match for call to `(std::tr1::reference_wrapper<int (test_type::*)(char)>)
(int, int)'
/usr/local/gcc/4.0.2/lib/gcc/i686-pc-linux-gnu/4.0.2/../../../../include/c++/4.0.2/tr1/ref_wrap_iterate.h:42:
note: candidates are: typename std::tr1::result_of<typename
std::tr1::_Function_to_function_pointer<_Tp,
std::tr1::is_function<_Tp>::value>::type ()()>::type
std::tr1::reference_wrapper<_Tp>::operator()() const [with _Tp = int
(test_type::*)(char)]
/usr/local/gcc/4.0.2/lib/gcc/i686-pc-linux-gnu/4.0.2/../../../../include/c++/4.0.2/tr1/functional_iterate.h:169:
note:                 typename std::tr1::result_of<typename
std::tr1::reference_wrapper<_Tp>::_M_func_type ()(_T1, _T2)>::type
std::tr1::reference_wrapper<_Tp>::operator()(_T1&, _T2&) const [with _T1 = int,
_T2 = int, _Tp = int (test_type::*)(char)]
/home/john/boost/libs/tr1/test/test_reference_wrapper_tricky.cpp:69: error: no
match for call to `(std::tr1::reference_wrapper<int (test_type::*)()const>)
(int, int)'
/usr/local/gcc/4.0.2/lib/gcc/i686-pc-linux-gnu/4.0.2/../../../../include/c++/4.0.2/tr1/ref_wrap_iterate.h:42:
note: candidates are: typename std::tr1::result_of<typename
std::tr1::_Function_to_function_pointer<_Tp,
std::tr1::is_function<_Tp>::value>::type ()()>::type
std::tr1::reference_wrapper<_Tp>::operator()() const [with _Tp = int
(test_type::*)()const]
/usr/local/gcc/4.0.2/lib/gcc/i686-pc-linux-gnu/4.0.2/../../../../include/c++/4.0.2/tr1/functional_iterate.h:169:
note:                 typename std::tr1::result_of<typename
std::tr1::reference_wrapper<_Tp>::_M_func_type ()(_T1, _T2)>::type
std::tr1::reference_wrapper<_Tp>::operator()(_T1&, _T2&) const [with _T1 = int,
_T2 = int, _Tp = int (test_type::*)()const]
/home/john/boost/libs/tr1/test/test_reference_wrapper_tricky.cpp:71: error: no
match for call to `(std::tr1::reference_wrapper<functor1>) (int, int)'
/usr/local/gcc/4.0.2/lib/gcc/i686-pc-linux-gnu/4.0.2/../../../../include/c++/4.0.2/tr1/ref_wrap_iterate.h:42:
note: candidates are: typename std::tr1::result_of<typename
std::tr1::_Function_to_function_pointer<_Tp,
std::tr1::is_function<_Tp>::value>::type ()()>::type
std::tr1::reference_wrapper<_Tp>::operator()() const [with _Tp = functor1]
/usr/local/gcc/4.0.2/lib/gcc/i686-pc-linux-gnu/4.0.2/../../../../include/c++/4.0.2/tr1/functional_iterate.h:169:
note:                 typename std::tr1::result_of<typename
std::tr1::reference_wrapper<_Tp>::_M_func_type ()(_T1, _T2)>::type
std::tr1::reference_wrapper<_Tp>::operator()(_T1&, _T2&) const [with _T1 = int,
_T2 = int, _Tp = functor1]


-- 
           Summary: reference_wrapper and pointers to member functions
           Product: gcc
           Version: 4.0.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: john at johnmaddock dot co dot uk
 GCC build triplet: linux.x86
  GCC host triplet: linux.x86
GCC target triplet: linux.x86


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24803

Reply via email to