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