|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
I shall be thankful for the with the following:
Class declaration: template <int Index, int Prio, int Dir> class cNHI_Task : public cChnlTask, cNHI_DTS { .... virtual void Body(); } I should like to have two different methods "Body" for Dir=0 and Dir=1. But all my attempts like: template <int Index, int Prio, int Dir> void cNHI_Task<Index, Prio, 1>::Body() {} or template <int Index, int Prio> void cNHI_Task<Index, Prio, 1>::Body() {} or similar failed. Studing the internet for hours dos not ... ![]() Any comments, please? -- Posted via a free Usenet account from http://www.teranews.com |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Feb 24, 7:30pm, Leon Pollak <le...@plris.com> wrote:
> I shall be thankful for the with the following: > > Class declaration: > template <int Index, int Prio, int Dir> > class cNHI_Task : public cChnlTask, cNHI_DTS { > ... > virtual void Body(); > > } > > I should like to have two different methods "Body" for Dir=0 and Dir=1.. But > all my attempts like: > > template <int Index, int Prio, int Dir> > void cNHI_Task<Index, Prio, 1>::Body() {} > > or > > template <int Index, int Prio> > void cNHI_Task<Index, Prio, 1>::Body() {} > > or similar failed. > > Studing the internet for hours dos not ... ![]() > > Any comments, please? You cannot have 2 bodies for the same function of the same template. You would need to specialize the class template for Dir = 1 and Dir = 2 individually, in order to achieve that. I tried making the member function Body() as a template but even that would not work as specializing a member template without specializing the class template is not allowed. Moreover, virtual member function templates are not allowed. Here is how you would specialize your class cNHI_Task: class cChnlTask{}; class cNHI_DTS{}; template <int Index, int Prio, int Dir> class cNHI_Task : public cChnlTask, cNHI_DTS { public: virtual void Body() { std::cout << "Dir = " << Dir << std::endl; } }; template <int Index, int Prio> class cNHI_Task <Index,Prio,1> : public cChnlTask, cNHI_DTS { public: virtual void Body() { std::cout << "Specialization : Dir = " << 1 << std::endl; } }; template <int Index, int Prio> class cNHI_Task <Index,Prio,2> : public cChnlTask, cNHI_DTS { public: virtual void Body() { std::cout << "Specialization : Dir = " << 2 << std::endl; } }; int main() { cNHI_Task<0,0,1> obj_dir_1; cNHI_Task<0,0,2> obj_dir_2; cNHI_Task<0,0,3> obj_dir_3; obj_dir_1.Body(); obj_dir_2.Body(); obj_dir_3.Body(); } |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Thank you Abhishek.
Your answer is complete and clear. The only question I still have is: why in the case of one parameter in the template everything works fine? I mean, I can do explicit specification like template<> ..... And in this case I do can have several bodies of the same function! Thanks ahead Abhishek Padmanabh wrote: > On Feb 24, 7:30Âpm, Leon Pollak <le...@plris.com> wrote: >> I shall be thankful for the with the following: >> >> Class declaration: >> template <int Index, int Prio, int Dir> >> class cNHI_Task : public cChnlTask, cNHI_DTS { >> ... >> virtual void Body(); >> >> } >> >> I should like to have two different methods "Body" for Dir=0 and Dir=1. >> But all my attempts like: >> >> template <int Index, int Prio, int Dir> >> void cNHI_Task<Index, Prio, 1>::Body() {} >> >> or >> >> template <int Index, int Prio> >> void cNHI_Task<Index, Prio, 1>::Body() {} >> >> or similar failed. >> >> Studing the internet for hours dos not ... ![]() >> >> Any comments, please? > > You cannot have 2 bodies for the same function of the same template. > You would need to specialize the class template for Dir = 1 and Dir = > 2 individually, in order to achieve that. > > I tried making the member function Body() as a template but even that > would not work as specializing a member template without specializing > the class template is not allowed. Moreover, virtual member function > templates are not allowed. > > Here is how you would specialize your class cNHI_Task: > > class cChnlTask{}; > class cNHI_DTS{}; > > template <int Index, int Prio, int Dir> > class cNHI_Task : public cChnlTask, cNHI_DTS { > public: > virtual void Body() > { > std::cout << "Dir = " << Dir << std::endl; > } > }; > > template <int Index, int Prio> > class cNHI_Task <Index,Prio,1> : public cChnlTask, cNHI_DTS { > public: > virtual void Body() > { > std::cout << "Specialization : Dir = " << 1 << std::endl; > } > }; > > template <int Index, int Prio> > class cNHI_Task <Index,Prio,2> : public cChnlTask, cNHI_DTS { > public: > virtual void Body() > { > std::cout << "Specialization : Dir = " << 2 << std::endl; > } > }; > > int main() > { > cNHI_Task<0,0,1> obj_dir_1; > cNHI_Task<0,0,2> obj_dir_2; > cNHI_Task<0,0,3> obj_dir_3; > obj_dir_1.Body(); > obj_dir_2.Body(); > obj_dir_3.Body(); > } -- Posted via a free Usenet account from http://www.teranews.com |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On Feb 24, 9:09pm, Leon Pollak <le...@plris.com> wrote:
> The only question I still have is: why in > the case of one parameter in the template everything works fine? Sorry, but I did not understand what you ask here. What do you mean by one parameter in template? > I mean, I > can do explicit specification like > template<> ..... > And in this case I do can have several bodies of the same function! If you do explicit specialization of your class, you can have any number of bodies of that function but that will be equal to the number of specializations you provide. That will also depends on what values of Index and Prio do you specialize them for. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
And just to clarify your decision:
The template class has many other methods. Your method involves the necessity to duplicate everything in declaration, yes? Thanks ahead. > Thank you Abhishek. > Your answer is complete and clear. The only question I still have is: why > in the case of one parameter in the template everything works fine? I > mean, I can do explicit specification like > template<> ..... > And in this case I do can have several bodies of the same function! > > Thanks ahead > > Abhishek Padmanabh wrote: > >> On Feb 24, 7:30Âpm, Leon Pollak <le...@plris.com> wrote: >>> I shall be thankful for the with the following: >>> >>> Class declaration: >>> template <int Index, int Prio, int Dir> >>> class cNHI_Task : public cChnlTask, cNHI_DTS { >>> ... >>> virtual void Body(); >>> >>> } >>> >>> I should like to have two different methods "Body" for Dir=0 and Dir=1. >>> But all my attempts like: >>> >>> template <int Index, int Prio, int Dir> >>> void cNHI_Task<Index, Prio, 1>::Body() {} >>> >>> or >>> >>> template <int Index, int Prio> >>> void cNHI_Task<Index, Prio, 1>::Body() {} >>> >>> or similar failed. >>> >>> Studing the internet for hours dos not ... ![]() >>> >>> Any comments, please? >> >> You cannot have 2 bodies for the same function of the same template. >> You would need to specialize the class template for Dir = 1 and Dir = >> 2 individually, in order to achieve that. >> >> I tried making the member function Body() as a template but even that >> would not work as specializing a member template without specializing >> the class template is not allowed. Moreover, virtual member function >> templates are not allowed. >> >> Here is how you would specialize your class cNHI_Task: >> >> class cChnlTask{}; >> class cNHI_DTS{}; >> >> template <int Index, int Prio, int Dir> >> class cNHI_Task : public cChnlTask, cNHI_DTS { >> public: >> virtual void Body() >> { >> std::cout << "Dir = " << Dir << std::endl; >> } >> }; >> >> template <int Index, int Prio> >> class cNHI_Task <Index,Prio,1> : public cChnlTask, cNHI_DTS { >> public: >> virtual void Body() >> { >> std::cout << "Specialization : Dir = " << 1 << std::endl; >> } >> }; >> >> template <int Index, int Prio> >> class cNHI_Task <Index,Prio,2> : public cChnlTask, cNHI_DTS { >> public: >> virtual void Body() >> { >> std::cout << "Specialization : Dir = " << 2 << std::endl; >> } >> }; >> >> int main() >> { >> cNHI_Task<0,0,1> obj_dir_1; >> cNHI_Task<0,0,2> obj_dir_2; >> cNHI_Task<0,0,3> obj_dir_3; >> obj_dir_1.Body(); >> obj_dir_2.Body(); >> obj_dir_3.Body(); >> } > > -- Posted via a free Usenet account from http://www.teranews.com |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Leon Pollak wrote:
> Thank you Abhishek. > Your answer is complete and clear. The only question I still have is: why in > the case of one parameter in the template everything works fine? I mean, I > can do explicit specification like > template<> ..... > And in this case I do can have several bodies of the same function! What you're trying to do here is called partial specialization; i.e. you're fixing one of the template parameters but leaving the rest unspecified. You can do this with class/struct templates but not with function templates as you're trying to do here. When you specialize a function template you have to fix all of the parameters, not just some of them. You can generally get around this by making use of a er class template, e.g. template <int Index, int Prio, int Dir> struct my_er; template <int Index, int Prio> struct my_er< Index, Prio, 0 > { static void DoBody() { // Body for Dir=0 } } template <int Index, int Prio> struct my_er< Index, Prio, 1 > { static void DoBody() { // Body for Dir=1 } } template <int Index, int Prio, int Dir> class cNHI_Task : public cChnlTask, cNHI_DTS { ... virtual void Body() { my_er< Index, Prio, Dir >::Run(); } }; Hope this answers your question. Colin |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
> What you're trying to do here is called partial specialization;
> [snip] Sorry, I just looked at your example again and realize that you're not trying to partially specialize a function template at all, you're trying to provide alternative implementations of a non-templated member function depending on one of the parameters of the surrounding class template. This also can't be done, and the solution (or at least a possible solution) is the same as the one I posted earlier. Colin |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
Wow!!!!!!!!!
Great!!!!!!! This is exactly what I need!!!! Thousands of thanks!!!!!!!!!!!! Colin Caughie wrote: > Leon Pollak wrote: >> Thank you Abhishek. >> Your answer is complete and clear. The only question I still have is: why >> in the case of one parameter in the template everything works fine? I >> mean, I can do explicit specification like >> template<> ..... >> And in this case I do can have several bodies of the same function! > > What you're trying to do here is called partial specialization; i.e. > you're fixing one of the template parameters but leaving the rest > unspecified. > > You can do this with class/struct templates but not with function > templates as you're trying to do here. When you specialize a function > template you have to fix all of the parameters, not just some of them. > > You can generally get around this by making use of a er class > template, e.g. > > template <int Index, int Prio, int Dir> > struct my_er; > > template <int Index, int Prio> > struct my_er< Index, Prio, 0 > > { > static void DoBody() > { > // Body for Dir=0 > } > } > > template <int Index, int Prio> > struct my_er< Index, Prio, 1 > > { > static void DoBody() > { > // Body for Dir=1 > } > } > > template <int Index, int Prio, int Dir> > class cNHI_Task : public cChnlTask, cNHI_DTS { > ... > virtual void Body() > { > my_er< Index, Prio, Dir >::Run(); > } > }; > > Hope this answers your question. > > Colin -- Posted via a free Usenet account from http://www.teranews.com |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
I tried the suggestion - the main obstacle of defining the Body is overcame.
But the Body itself is almost useless... ![]() Each attempt to use the class data elements is impossible: ....: error: invalid use of member 'any member from the class' in static member function What I do incorrect? Thanks a lot for your . > Leon Pollak wrote: >> Thank you Abhishek. >> Your answer is complete and clear. The only question I still have is: why >> in the case of one parameter in the template everything works fine? I >> mean, I can do explicit specification like >> template<> ..... >> And in this case I do can have several bodies of the same function! > > What you're trying to do here is called partial specialization; i.e. > you're fixing one of the template parameters but leaving the rest > unspecified. > > You can do this with class/struct templates but not with function > templates as you're trying to do here. When you specialize a function > template you have to fix all of the parameters, not just some of them. > > You can generally get around this by making use of a er class > template, e.g. > > template <int Index, int Prio, int Dir> > struct my_er; > > template <int Index, int Prio> > struct my_er< Index, Prio, 0 > > { > static void DoBody() > { > // Body for Dir=0 > } > } > > template <int Index, int Prio> > struct my_er< Index, Prio, 1 > > { > static void DoBody() > { > // Body for Dir=1 > } > } > > template <int Index, int Prio, int Dir> > class cNHI_Task : public cChnlTask, cNHI_DTS { > ... > virtual void Body() > { > my_er< Index, Prio, Dir >::Run(); > } > }; > > Hope this answers your question. > > Colin -- Posted via a free Usenet account from http://www.teranews.com |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
Leon Pollak wrote:
> I tried the suggestion - the main obstacle of defining the Body is overcame. > But the Body itself is almost useless... ![]() > Each attempt to use the class data elements is impossible: > ...: error: invalid use of member 'any member from the class' in static > member function > > What I do incorrect? > > Thanks a lot for your . You need to do two things: 1. Pass a pointer or reference to the class instance to the er function. So it becomes static DoBody( cNHI_Task& task ) { } then in cNHI_Task::Body you pass *this to the er method. 2. If DoBody needs access to private or protected members of the class, make the er a friend: template <int Index, int Prio, int Dir> class cNHI_Task : public cChnlTask, cNHI_DTS { ... friend class my_er< Index, Prio, Dir >; }; I think that's right anyway, I don't have a compiler close to hand today... Colin |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
Colin Caughie wrote:
> Leon Pollak wrote: >> I tried the suggestion - the main obstacle of defining the Body is >> overcame. But the Body itself is almost useless... ![]() >> Each attempt to use the class data elements is impossible: >> ...: error: invalid use of member 'any member from the class' in static >> member function >> >> What I do incorrect? >> >> Thanks a lot for your . > > You need to do two things: > > 1. Pass a pointer or reference to the class instance to the er > function. So it becomes > > static DoBody( cNHI_Task& task ) > { > } > > then in cNHI_Task::Body you pass *this to the er method. > > 2. If DoBody needs access to private or protected members of the class, > make the er a friend: > > template <int Index, int Prio, int Dir> > class cNHI_Task : public cChnlTask, cNHI_DTS { > ... > friend class my_er< Index, Prio, Dir >; > }; > > I think that's right anyway, I don't have a compiler close to hand > today... > > Colin Thanks Colin, a lot. But don't you think this looks rather... well, strange? Too complex? ![]() It seems to me, that method suggested by Abhishek Padmanabh specializing the class template is more straight forward, isn't it? If yes, how do I eliminate the multiplication of all class elements declarations? Isee two ways, but both are not beautiful: - defining a macro - deriving new class based on cNHI_Task<A,B,0>. Thanks again. -- Posted via a free Usenet account from http://www.teranews.com |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
Leon Pollak wrote:
> Thanks Colin, a lot. > But don't you think this looks rather... well, strange? Too complex? > ![]() Arguably yes, but that's often the way with C++... Often the bestway of doing something looks a bit weird to the uninitiated. Just look at the Boost libraries, or even any STL implementation, to see what I mean. > It seems to me, that method suggested by Abhishek Padmanabh specializing > the class template is more straight forward, isn't it? > If yes, how do I eliminate the multiplication of all class elements > declarations? Isee two ways, but both are not beautiful: > - defining a macro > - deriving new class based on cNHI_Task<A,B,0>. Personally I'd avoid the macro route, mainly because things that hide behind preprocessor macros can obscure the syntax and make it difficult for others to figure out how your code works. The derivation route may or may not be preferable to delegating out to a separate class. Derivation can sometimes bring with it more baggage than you really need (e.g. the problems inherent in multiple inheritance; the class in your example already derives from two other classes), but other times is a useful tool. I'd recommend trying both ways and deciding which seems cleaner to you. Colin |
|
![]() |
| Outils de la discussion | |
|
|