[smart_ptr] explicit instantiation of boost::shared_ptr
Hi there, I got a bug report that the following code doesn't compile: #include <boost/tr1/memory.hpp> template class boost::shared_ptr<int>; int main(int, char**) {} The errors this gives under GCC 4.9 are as follows: In file included from /usr/include/boost/shared_ptr.hpp:17:0, from /usr/include/boost/tr1/memory.hpp:56, from foo3.cc:1: /usr/include/boost/smart_ptr/shared_ptr.hpp: In instantiation of 'typename boost::detail::sp_array_access<T>::type boost::shared_ptr<T>::operator[](std::ptrdiff_t) const [with T = int; typename boost::detail::sp_array_access<T>::type = void; std::ptrdiff_t = long int]': foo3.cc:2:23: required from here /usr/include/boost/smart_ptr/shared_ptr.hpp:663:22: error: return-statement with a value, in function returning 'void' [-fpermissive] return px[ i ]; This in particular is with boost 1.54. The problem is however present on master as well, where it also gives more errors relating to boost/core/demangle.hpp that I didn't look into. I went ahead to do some investigation in case the issue ends up being trivial. We can't use enable_if to disable a particular member function. Not unless it's a template. Making it a template would lead to a code like this: template <class U = T, class V = boost::disable_if <boost::is_void <boost::detail::sp_array_access< U >::type>, U>::type> boost::detail::sp_array_access< T >::type operator[] (etc. etc.); ... which is not C++98, and I don't have ideas how to C++98-ify it while also having it do what we want without breaking API. (The indirection through U may not be necessary, I'm not in fact sure, but that doesn't change anything.) One way that I can see is extracting element_type * px to a base class (say, boost::detail::sp_operator_at) that either does or does not define operator[] (which would then use the px). But that implies some amount of code motion, and not knowing what your position would be, I didn't want to blindly go ahead and start moving stuff around. So, would a patch to the effect described above be possibly acceptable? Thanks, Petr.
Hi, The easiest fix I can think of is to change return px[ i ]; to return static_cast< typename boost::detail::sp_array_access< T >::type
( px[ i ] );
This seems to work for me with the current develop (master should be the same). I get no other errors. -----Original Message----- From: Petr Machata Sent: Tuesday, November 11, 2014 21:55 To: Peter Dimov Cc: boost@lists.boost.org Subject: [smart_ptr] explicit instantiation of boost::shared_ptr Hi there, I got a bug report that the following code doesn't compile: #include <boost/tr1/memory.hpp> template class boost::shared_ptr<int>; int main(int, char**) {} The errors this gives under GCC 4.9 are as follows: In file included from /usr/include/boost/shared_ptr.hpp:17:0, from /usr/include/boost/tr1/memory.hpp:56, from foo3.cc:1: /usr/include/boost/smart_ptr/shared_ptr.hpp: In instantiation of 'typename boost::detail::sp_array_access<T>::type boost::shared_ptr<T>::operator[](std::ptrdiff_t) const [with T = int; typename boost::detail::sp_array_access<T>::type = void; std::ptrdiff_t = long int]': foo3.cc:2:23: required from here /usr/include/boost/smart_ptr/shared_ptr.hpp:663:22: error: return-statement with a value, in function returning 'void' [-fpermissive] return px[ i ]; This in particular is with boost 1.54. The problem is however present on master as well, where it also gives more errors relating to boost/core/demangle.hpp that I didn't look into. I went ahead to do some investigation in case the issue ends up being trivial. We can't use enable_if to disable a particular member function. Not unless it's a template. Making it a template would lead to a code like this: template <class U = T, class V = boost::disable_if <boost::is_void <boost::detail::sp_array_access< U >::type>, U>::type> boost::detail::sp_array_access< T >::type operator[] (etc. etc.); ... which is not C++98, and I don't have ideas how to C++98-ify it while also having it do what we want without breaking API. (The indirection through U may not be necessary, I'm not in fact sure, but that doesn't change anything.) One way that I can see is extracting element_type * px to a base class (say, boost::detail::sp_operator_at) that either does or does not define operator[] (which would then use the px). But that implies some amount of code motion, and not knowing what your position would be, I didn't want to blindly go ahead and start moving stuff around. So, would a patch to the effect described above be possibly acceptable? Thanks, Petr.
"Peter Dimov" <lists@pdimov.com> writes:
The easiest fix I can think of is to change
return px[ i ];
to
return static_cast< typename boost::detail::sp_array_access< T
::type ( px[ i ] );
Ah, clever, thanks! Do you want to track this issue somehow? Do I open a trac ticket, or create a pull request, or...?
This seems to work for me with the current develop (master should be the same). I get no other errors.
Those other errors were caused by wrong (missing) -I flags. Nothing of interest. Thanks, Petr.
Petr Machata <pmachata@redhat.com> writes:
return static_cast< typename boost::detail::sp_array_access< T >::type > ( px[ i ] );
Do you want to track this issue somehow? Do I open a trac ticket, or create a pull request, or...?
Actually, array_fail_array_access.cpp fails with this patch (as in, it compiles successfully, which is a failure). Arguably it's not a big deal that the subscription operator exists if it doesn't actually do anything. But I expect the base class variant would keep the test failing. Let me know what you think. Thanks, Petr.
Petr Machata wrote:
::type > ( px[ i ] ); ... Actually, array_fail_array_access.cpp fails with this patch (as in, it compiles successfully, which is a failure). Arguably it's not a big deal
return static_cast< typename boost::detail::sp_array_access< T that the subscription operator exists if it doesn't actually do anything. But I expect the base class variant would keep the test failing. Let me know what you think.
I've "fixed" the test instead (on develop).
participants (2)
-
Peter Dimov
-
Petr Machata