Connecting Tech Pros Worldwide Forums | Help | Site Map

(very) Simple Template Metaprogramming question

stdlib99@googlemail.com
Guest
 
Posts: n/a
#1: Sep 1 '08
Hi,

I have a simple question regarding templates and meta programming.

I am going to try and work my way through the C++ Template
Metaprogramming, a book by David Abrahams and Aleksey Gurtovoy. I’m
not doing this because I want to be a Meta Programming guru (because a
lot of that stuff looks too crazy for use in the real world).

Rather I want to learn heavyweight templates and this is the only
hardcode template book that has questions and answers (on the web).

Anyway I have got as far as the first exercise. I have done the
exercise but I’m getting a compile error below.

I’m using Visual Studio 2005, but I’m sure its not a compiler problem
– its just I don’t understand what is going on.

The compile error is on the line (full code below):

const type_info& info1a = typeid(add_const_ref<int>::type);

where the compiler does not like the ::type in the call to typeid.

The error is :

error C2955: 'add_const_ref_impl<false>::type_' : use of class
template requires template argument list
see declaration of 'add_const_ref_impl<false>::type_'
see reference to class template instantiation 'add_const_ref<T>' being
compiled
with
[
T=int
]

I’m obviously don’t understand what is going on here. I would expect
that buy the time the compiler has done its meta programming magic
add_const_ref<int>::type would be a real type and I could pass it into
typeID, however that looks wrong. I think I'm misunderstanding
something fundermetal here so I'm posting.

So my question is why does this line fail to compile. Should I be able
to pass add_const_ref<int>::type into typeid()?

Thanks

stdlib

Ps. sorry if this is in the wrong group!


//================================================== ==

// This is an answer to they very first exercise in the
// C++ Template Metaprogramming book.
// Its the impl of a function add_const_ref function which add adds
converts a supplied type into
// a const ref to that type.

#include <boost/type_traits/is_reference.hpp>
#include <iostream>

template <bool is_refstruct add_const_ref_impl
{};


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

};

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

};
//==========================================


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


int main()
{
const type_info& info1a = typeid(add_const_ref<int>::type); //
error C2955 here
const type_info& info2a = typeid(add_const_ref<int&>::type); //
error C2955 here

std::cout << info1a.name() << std::endl << info2a.name() <<
std::endl;

return 0;
}
//================================================== ==

bood
Guest
 
Posts: n/a
#2: Sep 1 '08

re: (very) Simple Template Metaprogramming question


On Sep 1, 9:38*pm, stdli...@googlemail.com wrote:
Quote:
Hi,
>
I have a simple question regarding templates and meta programming.
>
I am going to try and work my way through the C++ Template
Metaprogramming, a book by David Abrahams and Aleksey Gurtovoy. I’m
not doing this because I want to be a Meta Programming guru (because a
lot of that stuff looks too crazy for use in the real world).
>
Rather I want to learn heavyweight templates and this is the only
hardcode template book that has questions and answers (on the web).
>
Anyway I have got as far as the first exercise. *I have done the
exercise but I’m getting a compile error below.
>
I’m using Visual Studio 2005, but I’m sure its not a compiler problem
– its just I don’t understand what is going on.
>
The compile error is on *the line (full code below):
>
* const type_info& info1a = typeid(add_const_ref<int>::type);
>
where the compiler does not like the ::type in the call to typeid.
>
The error is :
>
error C2955: 'add_const_ref_impl<false>::type_' : use of class
template requires template argument list
see declaration of 'add_const_ref_impl<false>::type_'
see reference to class template instantiation 'add_const_ref<T>' being
compiled
* * * * with
* * * * [
* * * * * * T=int
* * * * ]
>
I’m obviously don’t understand what is going on here. I would expect
that buy the time the compiler has done its meta programming magic
add_const_ref<int>::type would be a real type and I could pass it into
typeID, however that looks wrong. I think I'm misunderstanding
something fundermetal here so I'm posting.
>
So my question is why does this line fail to compile. Should I be able
to pass add_const_ref<int>::type into typeid()?
>
Thanks
>
stdlib
>
Ps. sorry if this is in the wrong group!
>
//================================================== ==
>
// This is an answer to they very first exercise in the
// C++ Template Metaprogramming book.
// Its the impl of a function add_const_ref function which add adds
converts a supplied type into
// a const ref to that type.
>
#include <boost/type_traits/is_reference.hpp>
#include <iostream>
>
template <bool is_refstruct add_const_ref_impl
{};
>
template <>
struct add_const_ref_impl<false>
{
* template<typename T>
* struct type_
* {
* * typedef const T& type;
* };
>
};
>
template <>
struct add_const_ref_impl<true>
{
* template<typename T>
* struct type_
* {
* * typedef T type;
* };
>
};
>
//==========================================
>
template <class T>
struct add_const_ref
{
* static const bool is_ref = boost::is_reference<T>::value;
* typedef typename add_const_ref_impl<is_ref>::type_::type type;
>
};
>
int main()
{
* const type_info& info1a = typeid(add_const_ref<int>::type); *//
error C2955 here
* const type_info& info2a = typeid(add_const_ref<int&>::type); //
error C2955 here
>
* std::cout << info1a.name() << std::endl << info2a.name() <<
std::endl;
>
* return 0;}
>
//================================================== ==
I can see two things here:

First, when you reference add_const_ref_impl<is_ref>::type_::type in
add_const_ref, noticing add_const_ref_impl::type_ is also a template,
you should provide a template argument here too. This is what the
compiler complains about.

Second, in the statement typeid(add_const_ref<int>::type),
add_const_ref<int>::type will cause ambitious, you should add a
'typename' here:
typeid(typename add_const_ref<int>::type)
Jim Z. Shi
Guest
 
Posts: n/a
#3: Sep 2 '08

re: (very) Simple Template Metaprogramming question




stdlib99@googlemail.com wrote:
Quote:
template <class T>
struct add_const_ref
{
static const bool is_ref = boost::is_reference<T>::value;
typedef typename add_const_ref_impl<is_ref>::type_::type type;
try this:

typedef typename add_const_ref_impl<is_ref>::template type_<T>::type type;
Quote:
};
>
HTH,
jim
stdlib99@googlemail.com
Guest
 
Posts: n/a
#4: Sep 10 '08

re: (very) Simple Template Metaprogramming question


On Sep 2, 8:06 am, "Jim Z. Shi" <ji...@cisco.comwrote:
Quote:
stdli...@googlemail.com wrote:
Quote:
template <class T>
struct add_const_ref
{
static const bool is_ref = boost::is_reference<T>::value;
typedef typename add_const_ref_impl<is_ref>::type_::type type;
>
try this:
>
typedef typename add_const_ref_impl<is_ref>::template type_<T>::type type;
>
Quote:
};
>
HTH,
jim
Hi,

Thanks to both of you for taking the time to reply.

The compile errors were indeed becase of the
missing template argument for type_<T>. Id did not have to use the
template Keyword
as VisualStudio 2008 was able to itendify the type_T<Tas a teample.

I as so made a mistake with the use of typeid():

I was expecting info1a.name() and info2a.name() to be different where
info2a.name would
be a const int&. But that is not the case as typeid() discards all the
const/ref info
so typeid(const int&) == typeid(int).
Quote:
HTH,
jim
Closed Thread


Similar C / C++ bytes