Problem with simple type extraction

Hi there, I cannot understand why the code below gives me a static assertion. As far as I know I use a very common technique to to extract a type from templated class using specialization over this class. #include <boost/assert.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/gil/gil_all.hpp> namespace boost { namespace gil { template< typename T > struct bit_field_type{ typedef T type; }; template< typename BitField, typename ChannelBitSizes, typename Layout, bool IsMutable > struct bit_field_type< bit_aligned_pixel_reference< BitField , ChannelBitSizes , Layout , IsMutable > > { typedef BitField type; }; } // namespace gil } // namespace boost int main(int argc, char* argv[]) { typedef boost::gil::bit_aligned_image1_type< 1, boost::gil::gray_layout_t >::type gray1_image_t; typedef gray1_image_t::view_t::reference ref; typedef boost::gil::bit_field_type< ref >::type bit_field_t; BOOST_STATIC_ASSERT(( boost::is_same< bit_field_t, unsigned char >::value )); return 0; } The type for gray1_image_t::view_t::reference is the following: boost::gil::bit_aligned_pixel_reference< unsigned char, boost::mpl::vector1_c< unsigned int, 1 > , boost::gil::layout< boost::mpl::vector1< boost::gil::gray_color_t >, boost::mpl::range_c< int, 0, 1> > , 1 > Can somebody tell what wrong. I have been staring at this for too long. I'm using MS Visual Studio 9 and 10. Thanks in advance, Christian

Hi Christian, On Mon, Aug 16, 2010 at 8:49 AM, Christian Henning <chhenning@gmail.com> wrote:
Hi there, I cannot understand why the code below gives me a static assertion. As far as I know I use a very common technique to to extract a type from templated class using specialization over this class.
I was surprised that this didn't work as well. After some investigation, I found that adding a 'const' to the specialization worked for me:
template< typename BitField, typename ChannelBitSizes, typename Layout, bool IsMutable > struct bit_field_type</* change here*/ const bit_aligned_pixel_reference< BitField , ChannelBitSizes , Layout , IsMutable > > { typedef BitField type; };
It wasn't working because the unspecialized bit_field_type was getting instantiated instead. HTH, Nate

Hi Nathan, On Mon, Aug 16, 2010 at 12:09 PM, Nathan Crookston <nathan.crookston@gmail.com> wrote:
Hi Christian,
On Mon, Aug 16, 2010 at 8:49 AM, Christian Henning <chhenning@gmail.com> wrote:
Hi there, I cannot understand why the code below gives me a static assertion. As far as I know I use a very common technique to to extract a type from templated class using specialization over this class.
I was surprised that this didn't work as well. After some investigation, I found that adding a 'const' to the specialization worked for me:
It works for me now too. Any idea why that is? Thank you very much! I have spend way too much time for these couple of lines of code. ;-) Christian

On Mon, Aug 16, 2010 at 12:32 PM, Christian Henning <chhenning@gmail.com> wrote:
It works for me now too. Any idea why that is?
Well, apparently the reference type is declared as const somewhere in the GIL code (not the referenced pixel, of course). I tried to find exactly where the const was added in the code, but I had some trouble following all the many metafunction instantiations, etc -- there are quite a few for the declaration given. I did modify the metafunction slightly to give correct results regardless of const (and volatile) qualifiers. Perhaps it would be of use to you: //In addition to previous includes #include <boost/type_traits/remove_cv.hpp> namespace boost { namespace gil { template< typename T > struct bit_field_type_impl { typedef T type; }; template< typename BitField, typename ChannelBitSizes, typename Layout, bool IsMutable > struct bit_field_type_impl< bit_aligned_pixel_reference< BitField , ChannelBitSizes , Layout , IsMutable > > { typedef BitField type; }; template< typename T > struct bit_field_type : bit_field_type_impl<typename boost::remove_cv<T>::type > {}; } // namespace gil } // namespace boost Thanks, Nate

Hi Nathan, On Mon, Aug 16, 2010 at 3:15 PM, Nathan Crookston <nathan.crookston@gmail.com> wrote:
On Mon, Aug 16, 2010 at 12:32 PM, Christian Henning <chhenning@gmail.com> wrote:
It works for me now too. Any idea why that is?
Well, apparently the reference type is declared as const somewhere in the GIL code (not the referenced pixel, of course). I tried to find exactly where the const was added in the code, but I had some trouble following all the many metafunction instantiations, etc -- there are quite a few for the declaration given.
I did not think of const since I thought there is gray1_image_t::view_t::const_reference. Turns out there isn't a const_reference. And maybe I got fooled by the MSVC debugger which told me that there is no const in actual type of gray1_image_t::view_t::reference.
I did modify the metafunction slightly to give correct results regardless of const (and volatile) qualifiers. Perhaps it would be of use to you:
//In addition to previous includes #include <boost/type_traits/remove_cv.hpp>
namespace boost { namespace gil {
template< typename T > struct bit_field_type_impl { typedef T type; };
template< typename BitField, typename ChannelBitSizes, typename Layout, bool IsMutable > struct bit_field_type_impl< bit_aligned_pixel_reference< BitField , ChannelBitSizes , Layout , IsMutable > > { typedef BitField type; };
template< typename T > struct bit_field_type : bit_field_type_impl<typename boost::remove_cv<T>::type > {};
} // namespace gil } // namespace boost
Thanks alot for your code suggestions I'll incorporate them into my code. Regards, Christian
participants (2)
-
Christian Henning
-
Nathan Crookston