By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,507 Members | 1,185 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,507 IT Pros & Developers. It's quick & easy.

(very) Simple Template Metaprogramming question

P: n/a
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;
}
//================================================== ==
Sep 1 '08 #1
Share this Question
Share on Google+
3 Replies


P: n/a
On Sep 1, 9:38*pm, stdli...@googlemail.com wrote:
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)
Sep 1 '08 #2

P: n/a


st******@googlemail.com wrote:
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;
};
HTH,
jim
Sep 2 '08 #3

P: n/a
On Sep 2, 8:06 am, "Jim Z. Shi" <ji...@cisco.comwrote:
stdli...@googlemail.com wrote:
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;
};

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).
HTH,
jim
Sep 10 '08 #4

This discussion thread is closed

Replies have been disabled for this discussion.