|
From: Road Dog on 7 Apr 2008 01:13 This seems to work fine: template <typename A, typename B, typename C> class D { }; template <typename A, typename C> class D<A, void, C> { }; but this: template <typename A, typename B, void (A::*MF)(B)> class D { }; template <typename A, void (A::*MF)()> class D<A, void, MF> class D { }; produces: test4.cc:17: error: invalid parameter type 'void' test4.cc:12: error: in declaration 'template<class T, class W, void (T::* MF)(W)> struct Whatever' test4.cc:17: error: '<type error>' is not a valid type for a template constant parameter This: class C<A, void, void (T::*MF)()> is no better. Is there some way to specialize on 'void' here ? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Thomas Maeder on 7 Apr 2008 07:26 Road Dog <noone(a)nowhere.com> writes: > template <typename A, typename B, typename C> > class D > { > }; > > template <typename A, typename C> > class D<A, void, C> > { > }; > > template <typename A, typename B, void (A::*MF)(B)> > class D > { > }; > > template <typename A, void (A::*MF)()> > class D<A, void, MF> > class D > { > }; > > produces: > > test4.cc:17: error: invalid parameter type 'void' > test4.cc:12: error: in declaration 'template<class T, class W, void > (T::* MF)(W)> struct Whatever' > test4.cc:17: error: '<type error>' is not a valid type for a template > constant parameter [It's always a bit irritating if people don't post the code that they have tested. The code you posted contains an obvious typo, and the parameters on (what the gcc error messages call) line 12 don't match the code.] Try this: template <typename A, typename B> class D<A, B, void (A::*)(B)> { }; template <typename A> class D<A, void, void (A::*)()> { }; -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel Krügler on 7 Apr 2008 07:39 On 7 Apr., 18:13, Road Dog <no...(a)nowhere.com> wrote: > This seems to work fine: > > template <typename A, typename B, typename C> > class D > { > > }; > > template <typename A, typename C> > class D<A, void, C> > { > > }; > > but this: > > template <typename A, typename B, void (A::*MF)(B)> > class D > { > > }; > > template <typename A, void (A::*MF)()> > class D<A, void, MF> > class D > { > > }; > > produces: > > test4.cc:17: error: invalid parameter type 'void' > test4.cc:12: error: in declaration 'template<class T, class W, void > (T::* MF)(W)> struct Whatever' > test4.cc:17: error: '<type error>' is not a valid type for a template > constant parameter > > This: > > class C<A, void, void (T::*MF)()> > > is no better. > > Is there some way to specialize on 'void' here ? Not exactly with the primary class template, that you provided above. The point is that any function type R()(A1) with typenames R and A1 will never match with something that actually has the pattern R()() which is essentially the same as R()(void) in C++, see [dcl.fct]/2: "[..] The parameter list (void) is equivalent to the empty parameter list. Except for this special case, void shall not be a parameter type [..]" Therefore, without variadic template parameters, it is impossible to express an empty parameter set given any type argument, e.g. C++0x would allow you to write a template like this template<class R, class ... Types> R f(Types ... args); *including* the case where args corresponds to the empty parameter set. Now being in C++03, what about the following approach, which has some further advantages, because it can be specialized for even more cases: template <typename T, T MF> class D; // Declared, not defined template<typename A, void (A::*MF)()> class D<void(A::*)(), MF> { }; template<typename A, typename B, void (A::*MF)(B)> class D<void(A::*)(B), MF> { }; struct W { void foo(); void bar(double); }; D<void(W::*)(), &W::foo> wf; D<void(W::*)(double), &W::bar> wb; HTH & Greetings from Bremen, Daniel Kr�gler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel Krügler on 7 Apr 2008 23:21 On 8 Apr., 00:26, Thomas Maeder <mae...(a)glue.ch> wrote: > Try this: > > template <typename A, typename B> > class D<A, B, void (A::*)(B)> > { > > }; > > template <typename A> > class D<A, void, void (A::*)()> > { > > }; Hmmh, OK, I throw in the towel: *How* did you define the primary class template that this works as written?? [You are right, that there is a blatant typo in the OP, but I don't think that above specialization is correct. For more details, see my seperate posting] Greetings from Bremen, Daniel Kr�gler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Thomas Maeder on 8 Apr 2008 04:36
Daniel Kr�gler <daniel.kruegler(a)googlemail.com> writes: > On 8 Apr., 00:26, Thomas Maeder <mae...(a)glue.ch> wrote: >> Try this: >> >> template <typename A, typename B> >> class D<A, B, void (A::*)(B)> >> { >> >> }; >> >> template <typename A> >> class D<A, void, void (A::*)()> >> { >> >> }; > > Hmmh, OK, I throw in the towel: *How* did you define the > primary class template that this works as written?? template <typename A, typename B, typename C> class D { }; > [You are right, that there is a blatant typo in the OP, but > I don't think that above specialization is correct. For more > details, see my seperate posting] I don't understand your point. Maybe because I don't understand the OP's intention, and you do. Or maybe vice versa :-) -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |