[Home]CPPTM Answers - Exercise 2-0

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

Difference (from prior major revision) (minor diff, author diff)

Changed: 65,111c65,137
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;
}
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


 // (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