[Home]CPPTM Answers - Exercise 2-0

BOOST WIKI | RecentChanges | Preferences | Page List | Links List

 // (by Ariel Badichi)
 #include <boost/static_assert.hpp>
 #include <boost/type_traits/is_same.hpp>
 #include <boost/type_traits/add_reference.hpp>
 #include <boost/type_traits/add_const.hpp>

 template<typename T>
 struct add_const_ref
 {
     typedef typename boost::add_const<T>::type ct;
     typedef typename boost::add_reference<ct>::type type;
 };

 template<typename T1, typename T2>
 void same()
 {
     const bool v = boost::is_same<T1, T2>::value;
     BOOST_STATIC_ASSERT(v);
 }

 int main()
 {
     same<const char &, add_const_ref<char>::type>();
     same<int * const &, add_const_ref<int *>::type>();
     same<int &, add_const_ref<int &>::type>();
     same<const long &, add_const_ref<const long &>::type>();
     return 0;
 }

 // My metafunction is just a bit different.
 // Above method makes better use of available tools, this one is more from scratch.

 template<typename T, bool B = is_reference<T>::value > struct add_const_ref;
 template<typename T> struct add_const_ref<T, true> { typedef T type; };
 template<typename T> struct add_const_ref<T, false> { typedef T const& type; };

// by Zedd

 template<typename T>
	struct add_const_ref
	{
		typedef T const& type ;
	} ;

 template<typename T>
	struct add_const_ref<T&>
	{
		typedef T& type ;
	} ;

What if T is int const? As per this template add_const_ref<int const>::type result in "int const const &". Isn't that wrong?

// comment by avjewe No, it's exactly right, in that this is true :

  boost::is_same<add_const_ref<int const>::type, int const &>::type::value
To me, this is clearly the "correct" answer.

// by JCR

The first solution does not seem satisfying because a reference to an int is going to become constant when it should not. I am not sure how the second solution works. My solution is below; I still find it quite complicated; any idea?

    template<bool b>
    struct add_const_ref_
    {
    };

    template<>
    struct add_const_ref_<true>
    {
      template<typename T>
      struct type_
      {
        typedef T type;
      };
    };

    template<>
    struct add_const_ref_<false>
    {
      template<typename T>
      struct type_
      {
        typedef T const& type;
      };
    };

    template<typename T>
    struct add_const_ref
    {
      static const bool test = boost::is_reference<T>::type::value;
      typedef typename add_const_ref_<test>::template type_<T>::type type;
    };

    template<typename T1, typename T2>
    struct Same
    {
      static const bool value = boost::is_same<T1, T2>::type::value;
    };

    int main (int argc, char ** argv)
    {
      std::cout << Same<add_const_ref<int&>::type, int&>::value << std::endl;//1
      std::cout << Same<add_const_ref<int&>::type, int const &>::value << std::endl;//0
      std::cout << Same<add_const_ref<int*>::type, int * const &>::value << std::endl;//1
      std::cout << Same<add_const_ref<int>::type, int const &>::value << std::endl;//1
      std::cout << Same<add_const_ref<const int &>::type, const int &>::value << std::endl;//1  
      return 0;
    }


I had to do the following in order to allow the line: BOOST_STATIC_ASSERT((boost::is_same<add_const_ref<int&>::type, int const&>::value)); to work...

    template<class T>
    class add_const_ref
    {
    public:
      typedef typename boost::add_reference
      <
        typename boost::add_const
        <
          typename boost::remove_reference
          <
            T
          >::type
        >::type
      >::type type;
    };

I used class and access control public because I personally dislike using "struct" for non-POD types. In the first example, the typedef ct is exposed so I nested the boost type traits. I think one could also have used private to avoid the nesting and still not expose the typedef ct.

-bessermt<e_@_mail>gmail.com


BOOST WIKI | RecentChanges | Preferences | Page List | Links List
Edit text of this page | View other revisions
Last edited January 6, 2008 5:37 pm (diff)
Search:
Disclaimer: This site not officially maintained by Boost Developers