Hello,

 

I am going through the book C++ Template Metaprogramming and wanted a sanity check on Exercise 2-0 from the book.

 

My first question is:  What would be a motivating example for why one would want a add_const_ref<T> metafunction that returned T if it was a reference and T const& otherwise?

 

My second question is:  How did I do? My guess is that the second crack is more correct.

 

Here is crack one:

 

My first crack at the exercise is below (my 2nd crack is below that)

#include <iostream>

#include <boost/type_traits/is_reference.hpp>

#include <boost/type_traits/is_same.hpp>

#include <boost/static_assert.hpp>

using namespace std;

 

template<typename T, bool>

struct add_const_ref

{

      typedef T const& value_type;

};

 

template<typename T>

struct add_const_ref<T, true>

{

      typedef T value_type;

};

 

 template<typename T>

 void func(typename add_const_ref<T, boost::is_reference<T>::value >::value_type t)

 {

 // .. do something   

 }

 

class BigClass

{

};

 

int main()

{

 

   int i = 0;

 

   BOOST_STATIC_ASSERT((boost::is_same<add_const_ref<int&, boost::is_reference<int&>::value >::value_type, int&>::value));

   BOOST_STATIC_ASSERT((boost::is_same<add_const_ref<int, boost::is_reference<int>::value >::value_type, int const&>::value));

 

   func<int&>(i);

 

   BigClass myBigClass;

   func<BigClass>(myBigClass);

  

   return 0;

}

 

After taking a look at add_reference.hpp in boost I modified my answer to the one below:

 

#include <iostream>

#include <boost/type_traits/is_reference.hpp>

#include <boost/type_traits/is_same.hpp>

#include <boost/static_assert.hpp>

using namespace std;

 

 

template<bool>

struct const_ref_adder

{

   template<typename T>

   struct result_

   {

      typedef T const& value_type;

   };

};

 

 

template<>

struct const_ref_adder<true>

{

template<typename T>

   struct result_

   {

       typedef T value_type;

   };

};

 

template<typename T>

struct add_const_ref

{

        typedef typename const_ref_adder<boost::is_reference<T>::value >::template result_<T>::value_type value_type;

 

};

 

 template<typename T>

 void func(typename add_const_ref<T>::value_type t)

 {

 // .. do something   

 }

 

class BigClass

{

};

 

int main()

{

 

   int i = 0;

 

   BOOST_STATIC_ASSERT((boost::is_same<add_const_ref<int&>::value_type, int&>::value));

   BOOST_STATIC_ASSERT((boost::is_same<add_const_ref<int>::value_type, int const&>::value));

 

   func<int&>(i);

 

   BigClass myBigClass;

   func<BigClass>(myBigClass);

  

   return 0;

}

 

Thanks in advance for your input,

 

Bruce