From: huili80 on
Hi everyone, I'm having trouble understand result of the following
simple case. Can someone help explaining what's going on there?
Thanks!

/////////////////////////////////////////////////////////////////////////////////////////

template < typename T >
struct A
{
template < typename U > struct B{};
};

template < typename V >
struct C
{
static const bool value = true;
};

template < typename X, typename Y >
struct C < typename A<X>::template B<Y> >
{
static const bool value = false;
};


int main()
{
if ( C< A<int>::B<double> >::value )
throw "Not what I thought it would be";

return 0;
}

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

From: Hakusa on
On Jun 21, 7:27 am, huil...(a)gmail.com wrote:
> Can someone help explaining what's going on there?
> Thanks!
>
> /////////////////////////////////////////////////////////////////////////////////////////
>
> template < typename T >
> struct A
> {
> template < typename U > struct B{};
>
> };
>
> template < typename V >
> struct C
> {
> static const bool value = true;
>
> };
>
> template < typename X, typename Y >
> struct C < typename A<X>::template B<Y> >
> {
> static const bool value = false;
>
> };
>
> int main()
> {
> if ( C< A<int>::B<double> >::value )
> throw "Not what I thought it would be";
>
> return 0;
>
> }
>
> --
> [ Seehttp://www.gotw.ca/resources/clcm.htmfor info about ]
> [ comp.lang.c++.moderated. First time posters: Do this! ]

Makes sense to me. C< type >'s value is true. C< type1, type2 >'s
value is false. But A<int>::B<double> is one type. Thus, C++ goes with
C< type > and not C< type1, type2 >. Get it?

But, this is confusing code. You should try to avoid situations like
this because, they might not confuse the compiler (always), but, as
you're demonstrating, they can easily fool you. The only place I ever
wanted to do this was when I built my own templated random function
(that called the standard rand()) and the compiler was able to tell
the difference, but since I never needed to call rand() directly,
neither of us had any issue.


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

From: Thomas Maeder on
huili80(a)gmail.com writes:

> I'm having trouble understand result of the following simple case.
> Can someone help explaining what's going on there?

Well, what would you expect? And what do you actually see?

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

From: Oncaphillis on
> template < typename X, typename Y >
> struct C < typename A<X>::template B<Y> >
> {
> static const bool value = false;
> };
>

Hmm, that doesn't even compile under g++ 4.3.0. Telling
me

<snip>
test.cc:16: error: template parameters not used in partial specialization:
test.cc:16: error: �X�
</snip>

This:

<snip>
> template < typename X, typename Y >
> struct C < typename A<X>::template B<Y>
</snip>

Looks like a partial specialization of class A<X>::B<Y>. In this
special case it's used as a template argument of the specialization
of C, but its still a specialization of a template within a templated
class and I think you only can do it if A<X> is fully specialized.
So e.g.

<snip>
template < typename Y >
struct C < typename A<int>::B<Y> >
{
static const bool value = false;
};
</snip>

keeps the compiler happy and gives you the desired results.

May be it's acceptable for you to move

template<typename U> struct B {}

into a un-templated base class of A like:

<snip>
struct A_base {
template < typename U > struct B{};
};

template < typename T >
struct A : public A_base
{
};
</snip>

and specialize C as

<snip>

template < typename Y >
struct C < typename A_base::B<Y> >
{
static const bool value = false;
};
</snip>

So you still get the semantics of "value has to be
false whenever I use A<X>::B<Y> no matter what
types X & Y may be". If however you'd like to
write more specializations (like for) A<float>::B<Y>
it won't work since c++ sees A<float>::B<Y> and
A_base::B<Y> as the same type and complains about
two identical specializations.

HTH

O.


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

From: huili80 on
On Jun 21, 3:52 pm, Thomas Maeder <mae...(a)glue.ch> wrote:
> huil...(a)gmail.com writes:
> > I'm having trouble understand result of the following simple case.
> > Can someone help explaining what's going on there?
>
> Well, what would you expect? And what do you actually see?

{ The clc++m banner is removed. Please don't quote it,
since it's automatically appended to every article in clc++m
and it's not part of what you're replying to. -mod }

I believe you must be able to guess my expectation and waht I actually
saw. I appologize for not having made it clear.

I was trying to partially specialize C<V> for the case that
V=A<X>::B<Y> (with arbitray types X and Y). But on the two compilers
that I've tested, apple-g++-4.0 and MSVC8, none of them was working
the way I wanted them to. But the code does compile, so I was hoping
to get an explaination.


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