C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Full explicit specialization of nested templated class

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Loban A Rahman
Guest





PostPosted: Wed Oct 12, 2005 12:58 am    Post subject: Full explicit specialization of nested templated class Reply with quote



Help! How do I make the following standards compliant:

template<typename T>
class Foo
{
struct bar
{
template<bool B>
struct moo
{
typedef tar& boo_type;
};

// FIXME: This section is the problem
template<>
struct moo<true>
{
typedef tar boo_type;
};
};

bar::moo<false>::boo_type a;
bar::moo<true>::boo_type b;
};


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Greg Herlihy
Guest





PostPosted: Wed Oct 12, 2005 8:53 am    Post subject: Re: Full explicit specialization of nested templated class Reply with quote



Loban A Rahman wrote:
Quote:
Help! How do I make the following standards compliant:

template<typename T
class Foo
{
struct bar
{
template struct moo
{
typedef tar& boo_type;
};

// FIXME: This section is the problem
template
struct moo {
typedef tar boo_type;
};
};

bar::moo bar::moo<true>::boo_type b;
};

The short answer is: you can't.

There is no standards compliant way to do what this program is
attempting. It is not possible in C++ to fully specialize a class
template nested inside a class template that is not itself specialized.
So you will have to consider alternate ways to achieve the desired
effect.

Personally, I try to avoid nested template declarations altogether. I
find that C++ templates are sufficiently difficult already and the
extra layer of type parameterization and the combinatorial "explosion"
of distinct instantiations as a result are, well, a bit over the top.

Instead of nesting Moo inside Foo, it should be possible to simulate
the relationship by "chaining" Moo to Foo, or by linking the types
through an additional level of abstraction.

For example, Moo could be declared a class template that is defined
only for instantiations of the class template Foo :

template <class T >
class Moo; // not defined

template <class T >
class Moo < Foo
{
...
};

Along the same lines, Moo could accept a template template parameter
which of course would be Foo:

template < template
class Moo
{
T<U> t_;
...

I would note that I do not know enough about the actual problem being
solved to propose either one of the ideas as a solution. Nevertheless,
I am confident that there exists at least some variation of one of
these approaches that would provide the structure that the program is
currently tryping to create with a nested class template.

Greg


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
werasm
Guest





PostPosted: Fri Oct 14, 2005 10:54 am    Post subject: Re: Full explicit specialization of nested templated class Reply with quote




Loban A Rahman wrote:
Quote:
Help! How do I make the following standards compliant:

Like this...

template<typename T>
class Foo
{
struct bar
{
template<bool B>
struct moo
{
typedef bar& boo_type;
};


// FIXME: This section is the problem
template<>
struct moo<true>
{
typedef bar boo_type;
};
};


typename bar::moo<false>::boo_type a;
typename bar::moo<true>::boo_type b;
};

Note <typename> before bar. I've only tried compilation under VC++ 7.1
- I do think it is standard, though. Strange that you don't have a bool
parameter in your outer nesting, though. What is the purpose?

Regards, Werner


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Loban A Rahman
Guest





PostPosted: Fri Oct 14, 2005 5:27 pm    Post subject: Re: Full explicit specialization of nested templated class Reply with quote

Done! Check it out. I used an anonymous namespace outside the class.

namespace
{
template<typename T>
struct no_qualifiers
{
typedef
typename boost::
remove_cv<typename boost::
remove_reference type>::
type
type;
};

template<typename T, bool B>
struct is_fund_switch
{
typedef
const typename no_qualifiers<T>::type&
type;
};
template<typename T>
struct is_fund_switch<T, true>
{
typedef
const typename no_qualifiers<T>::type
type;
};

template<typename T>
struct parameter
{
typedef
typename is_fund_switch<T, boost::is_fundamental::type
type;
};
}

template <typename T>
class Event
{
typedef typename parameter<T>::type parameter_type;

/* Code that uses parameter_type */
}


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Loban A Rahman
Guest





PostPosted: Fri Oct 14, 2005 5:38 pm    Post subject: Re: Full explicit specialization of nested templated class Reply with quote

Thanks for the reply, I think I have enough info now. However, since
you said you "don't know enough of the actual problem being solved",
I'm posting more of the actual code, in case you can give additional
advice.

#include <boost/type_traits.hpp>

template <typename T>
class Event
{
public:
/*
This handy typedef removes any const, volatile, or references
from the T type, which allows us to accept functions that take const
references to T as their parameter type. If we didn't do this, the
compiler would be trying to call Transmit(const const T &&object), and
since you can't have a reference to a reference, it wouldn't compile.
With this typedef, the call becomes Transmit(const T &object), which
is exactly what we want.
*/
typedef typename
boost::remove_cv<typename boost::remove_reference::type
no_qualifiers_T;

struct parameter
{
template<bool B>
struct is_fund_switch
{
typedef const no_qualifiers_T ¶m_type;
};

template<>
struct is_fund_switch<true>
{
typedef const no_qualifiers_T param_type;
};
};

/*
This typedef provides the final version of the parameter type that we
want to use in our function objects. It passes fundamental types
(ints, floats, void) as const T, which is the right way to pass simple
types, and passes all other types as const T &, the right way to pass
complex types.
*/
typedef typename
parameter::is_fund_switch<boost::is_fundamental::param_type
parameter_type;
};

Perhaps there's a simpler way to do this?


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Carl Barron
Guest





PostPosted: Sat Oct 15, 2005 12:55 pm    Post subject: Re: Full explicit specialization of nested templated class Reply with quote

Loban A Rahman <loban.rahman (AT) gmail (DOT) com> wrote:

Quote:
/*
This typedef provides the final version of the parameter type that we
want to use in our function objects. It passes fundamental types
(ints, floats, void) as const T, which is the right way to pass simple
types, and passes all other types as const T &, the right way to pass
complex types.
*/
typedef typename
parameter::is_fund_switch<boost::is_fundamental::param_type
parameter_type;
};

Perhaps there's a simpler way to do this?
doesn't boost/type_traits have a template to do this already? Boost

docs not handy right now.
call_traits<T>::param_type? or something similiar??
include boost/call_traits.hpp to get call_traits template [at least
that is what this older boost source says.("1_32" in version.hpp)]


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Greg Herlihy
Guest





PostPosted: Sat Oct 15, 2005 1:05 pm    Post subject: Re: Full explicit specialization of nested templated class Reply with quote


Loban A Rahman wrote:
Quote:
Thanks for the reply, I think I have enough info now. However, since
you said you "don't know enough of the actual problem being solved",
I'm posting more of the actual code, in case you can give additional
advice.

#include
...

Perhaps there's a simpler way to do this?

Since your implementation is already using boost type_traits, I would
look into using boost's call_traits.hpp as well. As far as I can tell,
call_traits.hpp does exactly what your code does: to figure out the
"best" parameter type for a given type.

Greg


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Valentin Samko
Guest





PostPosted: Sun Oct 16, 2005 9:40 am    Post subject: Re: Full explicit specialization of nested templated class Reply with quote

werasm wrote:
Quote:
Loban A Rahman wrote:

Help! How do I make the following standards compliant:


Like this...

template<typename T
class Foo
{
struct bar
{
template struct moo
{
typedef bar& boo_type;
};


// FIXME: This section is the problem
template
struct moo {
typedef bar boo_type;
};
};


typename bar::moo typename bar::moo<true>::boo_type b;
};

Note <typename> before bar. I've only tried compilation under VC++ 7.1
- I do think it is standard, though.

It is not. There is nothing in the standard that allows this syntax.
VC++ supports this as an extension (which really helps to implement
workarounds for VC6 which does not allow partial template specialisation).

--

Valentin Samko - http://val.samko.info

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
werasm
Guest





PostPosted: Mon Oct 17, 2005 2:00 pm    Post subject: Re: Full explicit specialization of nested templated class Reply with quote


Valentin Samko wrote:
Quote:
It is not. There is nothing in the standard that allows this syntax.
VC++ supports this as an extension (which really helps to implement
workarounds for VC6 which does not allow partial template specialisation).

Thank you for telling me. I've got another example - similar:

template<typename T, bool B1>
struct Foo
{
struct bar
{
template<bool B2>
struct moo
{
typedef bar& boo_type;
};


template<>
struct moo<true>
{
typedef bar boo_type;
};
};


typedef typename bar::moo<B1>::boo_type booType;
booType bt;
};

int main(int argc, char* argv[])
{
typedef Foo<int, true>::booType bt;
bt b;
return 0;
}

Note here the switch to template param <B2>. Would you agree that this
is iaw. standard? This is similar to an example I've seen in the 98 std
- 14.5.4.3 par. 2.

Can you perhaps point me to the par. in the standard disallowing this.

Tks,

W


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
werasm
Guest





PostPosted: Tue Oct 18, 2005 10:27 am    Post subject: Re: Full explicit specialization of nested templated class Reply with quote


werasm wrote:
Quote:
Valentin Samko wrote:

This is similar to an example I've seen in the 98 std
Quote:
- 14.5.4.3 par. 2.

Sorry, the example mentioned in std was only partially specialized.
Although I cannot quote that standard on this, it makes sense that you
cannot perform full specialization on a template nested inside a class
template. The reason I'm saying this, is that a full specialization is
not a class template (right?). It is a realization of a class template
(a known type). For the nested class to be known, the nesting class has
to be known too, which cannot be the case - therefore the full
specialization cannot be, as to qualify it the type/s associated with
the nesting class is to be known. Hope my rationale makes sense.

Example:

template <class T, bool B1>
struct Nesting
{
class Nested1
{
template <bool B2>
struct Nested2
{
typedef Nested1 type;
};

template <>
struct Nested2<true>
{
typedef Nested1& type;
};
};
};

typedef Nesting<int, true>::Nested1::Nested2<true> x;
....cannot be the same type as...
typedef Nesting<char, true>::Nested1::Nested2<true> x;
....because the nesting template's type varies, therefore this cannot be
considered as full specialization. And as you mentioned, it probably
only compiles under VC++ for the reason you stated (BTW, I did not test
this example, I only used it to explain my rationale).

Kind regards,

Werner


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Johan
Guest





PostPosted: Thu Oct 20, 2005 2:03 pm    Post subject: Re: Full explicit specialization of nested templated class Reply with quote

Since total specialization of inner structs is not allow, we can used a
trick to simulate it with a partial specialization:

class Foo
{
// The default argument will not change the call in the user code.
template<bool B, typename Dummy = void>
struct Moo
{
typedef int* type;
};

// partial specialization is accepted
template<typename Dummy>
struct Moo<true, Dummy>
{
typedef int type;
};
};

int main()
{
Foo::Moo<true>::type a = 42;
Foo::Moo<false>::type b = &a;
}


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Loban A Rahman
Guest





PostPosted: Fri Oct 28, 2005 9:39 am    Post subject: Re: Full explicit specialization of nested templated class Reply with quote

Greg Herlihy,

You are right! boost/call_traits.hpp does exactly what this code wants
to do. I'll inform the original programmer of this code about it. (I'm
just working on portability - his code works perfectly in Windows, I'm
working to get it portable to linux).


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.