Possible to write constructor templates within non-template classes ?

Possible to write constructor templates within non-template classes ?

Post by Amn » Wed, 23 Apr 2003 21:05:38



Hi all !

I know it is possible to write a constructor for a class template, like

template<class T> class A
{
    T i;

public:

    A(T _i): i(_i) { }

Quote:};

but is it possible to write a constructor template for a class ?

class Functor
{
public:

     template<class T, void (T::*pMember)()> Functor(T* pObj) {
(pObj->*pMember)(); }

Quote:};

It is important to me that class Functor remains a class, and not a template
even if it only implies minimum adjustments. I really need the latter
approach instead,
where a constructor template can be instantiated in a variery of forms,
depending on T type. I don't see any practical limitations for this
technique implemented. I dont have a draft on my hands, so was "guessing"
instantiating a Functor object could look something like:

class A
{
public:

    void f() { }

Quote:};

A obj;
Functor obj2<A, A::f>(&obj);

but i am getting:
error C2143: syntax error : missing ';' before '<'

So is it possible then to really write and use constructor templates for
class types ?

P.S. Functor is only an example, since there are already fine working
functor libraries out there, and i am not reinventing it here. I just need
to know ;)

 
 
 

Possible to write constructor templates within non-template classes ?

Post by Victor Bazaro » Wed, 23 Apr 2003 22:47:08



> I know it is possible to write a constructor for a class template, like

> template<class T> class A
> {
>     T i;

> public:

>     A(T _i): i(_i) { }
> };

> but is it possible to write a constructor template for a class ?

> class Functor
> {
> public:

>      template<class T, void (T::*pMember)()> Functor(T* pObj) {
> (pObj->*pMember)(); }
> };

Yes, it surely is.  Not in the form you suggested, though.

- Show quoted text -

Quote:> It is important to me that class Functor remains a class, and not a
template
> even if it only implies minimum adjustments. I really need the latter
> approach instead,
> where a constructor template can be instantiated in a variery of forms,
> depending on T type. I don't see any practical limitations for this
> technique implemented. I dont have a draft on my hands, so was "guessing"
> instantiating a Functor object could look something like:

> class A
> {
> public:

>     void f() { }
> };

> A obj;
> Functor obj2<A, A::f>(&obj);

> but i am getting:
> error C2143: syntax error : missing ';' before '<'

> So is it possible then to really write and use constructor templates for
> class types ?

Yes, of course.  I would do it this way, though:

    class Functor
    {
    public:
        template<class T> Functor(T* pObj, void (T::*pMember)())
        {
            (pObj->*pMember)();
        }
    };

    struct A
    {
        void foo();
    };

    int main()
    {
        A a;
        Functor f(&a, &A::foo);
    }

Quote:

> P.S. Functor is only an example, since there are already fine working
> functor libraries out there, and i am not reinventing it here. I just need
> to know ;)

Victor
--
Please remove capital A's from my address when replying by mail

 
 
 

Possible to write constructor templates within non-template classes ?

Post by Amn » Thu, 24 Apr 2003 04:14:19


Quote:

> Yes, it surely is.  Not in the form you suggested, though.

> Yes, of course.  I would do it this way, though:

>     class Functor
>     {
>     public:
>         template<class T> Functor(T* pObj, void (T::*pMember)())
>         {
>             (pObj->*pMember)();
>         }
>     };

>     struct A
>     {
>         void foo();
>     };

>     int main()
>     {
>         A a;
>         Functor f(&a, &A::foo);
>     }

Thanks,

The thing is that this was a simplified example of an issue i am dealing
with, where i actually tried to move template parameter to be a ctor
parameter,
as you did here. You see, i am using the technique in something like:

//This is a WINAPI specific

#include <windows.h>

class thread
{
    template<class T, DWORD (T::*pMember)()> friend DWORD WINAPI
functor(LPVOID pObj) { return (((T*)pObj)->*pMember)(); }

public:

    template<class T> thread(T* pObj, DWORD (T::*pMember)())
    {
        CreateThread(NULL, 0, functor<pObj, pMember>, pObj, 0, NULL);
    }

Quote:};

//end of code

WINAPI aside, not that it changes anything, i cannot pass a local variable
(pMember) further to be a parameter for functor template. That is why i
needed pMember to originally be a template parameter, so that it would be
evaluated at compile-time. And that leads to ctor template with explicit
template parameter needed, and by ISO draft, it is impossible to instantiate
ctors and conversion functions with explicit template parameters.

So i guess i am out of luck then ?

 
 
 

Possible to write constructor templates within non-template classes ?

Post by Victor Bazaro » Thu, 24 Apr 2003 04:36:05



> > Yes, it surely is.  Not in the form you suggested, though.

> > Yes, of course.  I would do it this way, though:

> >     class Functor
> >     {
> >     public:
> >         template<class T> Functor(T* pObj, void (T::*pMember)())
> >         {
> >             (pObj->*pMember)();
> >         }
> >     };

> >     struct A
> >     {
> >         void foo();
> >     };

> >     int main()
> >     {
> >         A a;
> >         Functor f(&a, &A::foo);
> >     }

> Thanks,

> The thing is that this was a simplified example of an issue i am dealing
> with, where i actually tried to move template parameter to be a ctor
> parameter,
> as you did here. You see, i am using the technique in something like:

> //This is a WINAPI specific

> #include <windows.h>

> class thread
> {
>     template<class T, DWORD (T::*pMember)()> friend DWORD WINAPI
> functor(LPVOID pObj) { return (((T*)pObj)->*pMember)(); }

> public:

>     template<class T> thread(T* pObj, DWORD (T::*pMember)())
>     {
>         CreateThread(NULL, 0, functor<pObj, pMember>, pObj, 0, NULL);
>     }
> };

> //end of code

> WINAPI aside, not that it changes anything, i cannot pass a local variable
> (pMember) further to be a parameter for functor template. That is why i
> needed pMember to originally be a template parameter, so that it would be
> evaluated at compile-time. And that leads to ctor template with explicit
> template parameter needed, and by ISO draft, it is impossible to
instantiate
> ctors and conversion functions with explicit template parameters.

> So i guess i am out of luck then ?

In that regard, probably.

Why can't you have a nested template class, whose member function
would do what you need:

class thread
{
    template<class T, DWORD (T::*pMember)()> struct creator
    {
        static go(T* o)
        {
            (((T*)o)->*pMember)();
        }
    };

public:
    template<class T> thread(T* pObj, DWORD (T::*pMember)())
    {
        CreateThread(NULL, 0, creator<pObj, pMember>::go,
                                            pObj, 0, NULL);
    }

Quote:};

Isn't it supposed to work?  Well, I can't really check it, since
I don't have the rest of your code, but you can, and besides, the
example is designed just to give you the idea...

Victor
--
Please remove capital A's from my address when replying by mail

 
 
 

Possible to write constructor templates within non-template classes ?

Post by Amn » Thu, 24 Apr 2003 05:00:38


Quote:>     template<class T> thread(T* pObj, DWORD (T::*pMember)())
>     {
>         CreateThread(NULL, 0, creator<pObj, pMember>::go,
>                                             pObj, 0, NULL);
>     }

Don't you think pMember would not be allowed as template parameter since it
is an automatic (and volatile) run-time local variable passed as a parameter
?
At least MSVC++ (i assume standard-wise it is right in this case) tells me
pMember is considered non-legitimate template argument, since no local
variables are allowed as template arguments, only globals, global constants
and immediate values.
after all the template has to be instantiated at compile-time, while pMember
is present in run-time as a parameter to function ?

If the above would work that would be a dream.....
But thank you, Victor.

 
 
 

Possible to write constructor templates within non-template classes ?

Post by Victor Bazaro » Thu, 24 Apr 2003 05:26:56



> >     template<class T> thread(T* pObj, DWORD (T::*pMember)())
> >     {
> >         CreateThread(NULL, 0, creator<pObj, pMember>::go,
> >                                             pObj, 0, NULL);
> >     }

> Don't you think pMember would not be allowed as template parameter since
it
> is an automatic (and volatile) run-time local variable passed as a
parameter
> ?

You're right.  That shouldn't work.  Sorry to have wasted your
time on this one.

Quote:> At least MSVC++ (i assume standard-wise it is right in this case) tells me
> pMember is considered non-legitimate template argument, since no local
> variables are allowed as template arguments, only globals, global
constants
> and immediate values.
> after all the template has to be instantiated at compile-time, while
pMember
> is present in run-time as a parameter to function ?

> If the above would work that would be a dream.....

To be entirely honest with you, I am still struggling to understand
why you want to go into such trouble just to create a thread...

Victor

 
 
 

Possible to write constructor templates within non-template classes ?

Post by Amn » Thu, 24 Apr 2003 05:55:42


Quote:> To be entirely honest with you, I am still struggling to understand
> why you want to go into such trouble just to create a thread...

I ll be glad to share the idea....yeah, i am known for my strangest ideas,
so anyway:
the idea is to create thread objects that could run foreign object class
members, in their context of course.
Practically this is usefull when you need some work done by some member of
some class, and that member function accesses the members of the class, as
usually object oriented programming works. But the difference is that this
member function is executing in parallel, in background, so to speak. Thats
only why i want to do this. Its not very common practice, but sometimes i
need it, and I decided to put it into a library to spare resources of
rewriting that stuff all the time.
 
 
 

Possible to write constructor templates within non-template classes ?

Post by Victor Bazaro » Thu, 24 Apr 2003 06:20:33



> > To be entirely honest with you, I am still struggling to understand
> > why you want to go into such trouble just to create a thread...

> I ll be glad to share the idea....yeah, i am known for my strangest ideas,
> so anyway:
> the idea is to create thread objects that could run foreign object class
> members, in their context of course.
> Practically this is usefull when you need some work done by some member of
> some class, and that member function accesses the members of the class, as
> usually object oriented programming works. But the difference is that this
> member function is executing in parallel, in background, so to speak.
Thats
> only why i want to do this. Its not very common practice, but sometimes i
> need it, and I decided to put it into a library to spare resources of
> rewriting that stuff all the time.

<shrug>  I still don't understand why this thread creation has
to be a template based on _two_ arguments.  Why can't you just
have one: the object type and always pass the pointer to member
function as a second argument?

#include <windows.h>
#include <stdio.h>

template<typename T> class memberthread {
    T* pObj;
    DWORD (T::*member)();

    static DWORD WINAPI adapter(void *pV) {
        memberthread *pT = (memberthread*)pV;
        T* pO = pT->pObj;
        return (pO->*(pT->member))();
    }

    HANDLE th;

public:
    memberthread(T* p, DWORD (T::*pm)())
        : pObj(p), member(pm), th(INVALID_HANDLE_VALUE) {}
    void run() {
        DWORD id;
        th = CreateThread(NULL, 0, adapter, this, 0, &id);
    }

    bool sync() {
        int c = WaitForSingleObject(th, INFINITE);
        return c == WAIT_OBJECT_0;
    }

Quote:};

struct A {
    DWORD foo() {
        Sleep(1000);
        puts("Hello from foo");
        Sleep(1000);
        puts("Good-bye from foo");
        return 0;
    }

    DWORD bar() {
        Sleep(1200);
        puts("Hello from bar");
        Sleep(1300);
        puts("Good-bye from bar");
        return 0;
    }

Quote:};

int main() {
    A a;

    memberthread<A> mt_a_foo(&a, &A::foo);
    memberthread<A> mt_a_bar(&a, &A::bar);

    mt_a_foo.run();
    mt_a_bar.run();

    mt_a_foo.sync();
    mt_a_bar.sync();

    puts("All done!");

    return 0;

Quote:}

Victor
--
Please remove capital A's from my address when replying by mail
 
 
 

1. Template method for non-template class possible?

I'm having my 1st experience with a C++ compiler that actually
supports templates (Metaware High C).  Something I would like to do
using a template appears to not be possible. I'm hoping someone can
confirm this or show me how to accomplish it.

Put simply I'd like to create a template function that is a member of
a class which is not a template class.  For example:

class archiveT {
    char data[1000];                         // archive data
    archiveT & operator <<(int & dataR);     //Copy an int to archive
    archiveT & operator <<(long & dataR);    //Copy a long to archive
    template <class TYPE>
    archiveT & operator <<(TYPE & dataR);    //Generic operator to
                                             //copy any type without
                                             //a specific << operator

I realize this syntax is invalid, but wondered if there is any way to
accomplish what I'm after.  I realize that the operator << could be
moved outside the class and written as:

template <class TYPE>
archiveT & operator <<(archiveT & archiveR, TYPE & dataR)

However the compiler then uses this template to generate operator <<
instances for the int and long operators already defined internal to
the class.  It then gives an error that there are two possible
functions to be called for:

archive << 5L;

To date my only solution is to move all declarations of the <<
operator outside the class.  Be aware that my example is simplfied and
I actually have 10 or more internal << operators defined which I'd
rather not move outside the class.  Any help would be appreciated.
Thanks in advance.

______________________________________________________
Jon D. Newbill, Software Consultant

Placing ones and zeros in the proper order is all I do!

______________________________________________________
Jon D. Newbill, Software Consultant

Placing ones and zeros in the proper order is all I do!
_______________________________________________________


      [ about comp.lang.c++.moderated. First time posters: do this! ]

2. PDA Beaming Stations

3. How to make a general template class friend of a non-template class?

4. WTB Sparc Portables Oldermodels

5. How to nest a non-template class in a template class ?

6. Newsgroup posting appears to be blocked

7. template members function in non-template classes

8. Application Popup

9. Template functions in non-template classes

10. Template method, non-template class

11. Template members of non-template classes

12. How to instantiate explicitly template member of non-template class??

13. deriving template classes from non-template one.