|
Prev: a confusing behavior for int=double
Next: How to impliment searching the definition of a c/c++ function in a c/c++ source file
From: huili80 on 20 Jun 2008 21:27 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 21 Jun 2008 04:51 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 21 Jun 2008 04:52 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 21 Jun 2008 06:45 > 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 21 Jun 2008 17:57
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! ] |