CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Apr 2009
    Posts
    1,355

    templates - how define a parameter for recive a function name?

    can i do a template class parameter for recive a function name?

  2. #2
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: templates - how define a parameter for recive a function name?

    "no". functions can't be used as template typenames.

    but you'll have to explain better what you want to achieve, there may be ways to do what you want.

    a functor or lambda may "appear" to be what you want, even though what's really happening is a bit more convoluted than just a function call.

  3. #3
    Join Date
    Apr 2009
    Posts
    1,355

    Re: templates - how define a parameter for recive a function name?

    Quote Originally Posted by OReubens View Post
    "no". functions can't be used as template typenames.

    but you'll have to explain better what you want to achieve, there may be ways to do what you want.

    a functor or lambda may "appear" to be what you want, even though what's really happening is a bit more convoluted than just a function call.
    finaly i fix it:
    Code:
    template <typename Container, typename ValueType, void (Container::*setptr)(ValueType t),ValueType (Container::*getptr)(void),Container cObject, int nPropType=3>
    class property2
    {
    i have another question: how can i do another parameter for accept the class pointer(this)?

  4. #4
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: templates - how define a parameter for recive a function name?

    What is the bigger picture of what you are trying to do?
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  5. #5
    Join Date
    Apr 2009
    Posts
    1,355

    Re: templates - how define a parameter for recive a function name?

    Quote Originally Posted by laserlight View Post
    What is the bigger picture of what you are trying to do?
    i'm updating the property template class:
    Code:
    template <typename Container,const Container *otherClass, typename ValueType, void (Container::*setptr)(ValueType t)=NULL,ValueType (Container::*getptr)(void)=NULL, int nPropType=3>
    class property2
    {
    public:
        property2()
        {
            m_cObject= otherClass;
            Set = setptr;
            Get = getptr;
        }
    
        //-- Overload the '=' sign to set the value using the set
        //   member --
        ValueType operator =(const ValueType& value)
        {
            assert(m_cObject != NULL);
            assert(Set != NULL);
            (m_cObject->*Set)(value);
            return value;
        }
    
        //-- To make possible to cast the property class to the
        //   internal type --
        operator ValueType()
        {
            assert(m_cObject != NULL);
            assert(Get != NULL);
            return (m_cObject->*Get)();
        }
        friend istream &operator>>( istream  &input, property2 &d )
        {
            ValueType v;
            input >>v;
            d = v;
            return input;
        }
    
    
        friend istream& getline (istream&  is, property2 &str)
        {
            ValueType v;
            getline(is,v);
            str = v;
            return is;
        }
    
    private:
      Container* m_cObject;  //-- Pointer to the module that
                             //   contains the property --
      void (Container::*Set)(ValueType value);
                             //-- Pointer to set member function --
      ValueType (Container::*Get)();
                             //-- Pointer to get member function --
    };
    from these updated(by me):
    Code:
    template <typename Container, typename ValueType, int nPropType=3>
    class property
    {
    public:
        property()
        {
            m_cObject = NULL;//error:(
    
                Set = NULL;
    
                Get = NULL;
        }
    
    
        //-- This to set a pointer to the class that contain the
        //   property --
        void setContainer(Container* cObject)
        {
            m_cObject = cObject;
        }
    
    
        //-- Set the set member function that will change the value --
        void setter(void (Container::*pSet)(ValueType value))
        {
            if((nPropType == WRITE_ONLY) || (nPropType == READ_WRITE))
                Set = pSet;
            else
                Set = NULL;
        }
    
    
        //-- Set the get member function that will retrieve the value --
        void getter(ValueType (Container::*pGet)())
        {
            if((nPropType == READ_ONLY) || (nPropType == READ_WRITE))
                Get = pGet;
            else
                Get = NULL;
        }
    
    
        //-- Overload the '=' sign to set the value using the set
        //   member --
        ValueType operator =(const ValueType& value)
        {
            assert(m_cObject != NULL);
            assert(Set != NULL);
            (m_cObject->*Set)(value);
            return value;
        }
    
        //-- To make possible to cast the property class to the
        //   internal type --
        operator ValueType()
        {
            assert(m_cObject != NULL);
            assert(Get != NULL);
            return (m_cObject->*Get)();
        }
        friend istream &operator>>( istream  &input, property &d )
        {
            ValueType v;
            input >>v;
            d = v;
            return input;
        }
    
    
        friend istream& getline (istream&  is, property& str)
        {
            ValueType v;
            getline(is,v);
            str = v;
            return is;
        }
    
    private:
      Container* m_cObject;  //-- Pointer to the module that
                             //   contains the property --
      void (Container::*Set)(ValueType value);
                             //-- Pointer to set member function --
      ValueType (Container::*Get)();
                             //-- Pointer to get member function --
    };
    but i need put the 'this' in parameter list for finish the class. buti don't know do that parameter
    what is the diference between porperty and property2: i want, in porperty2, declare a property using a single code line. that's why i'm doing these
    Last edited by Cambalinho; September 26th, 2013 at 10:50 AM.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: templates - how define a parameter for recive a function name?

    Quote Originally Posted by Cambalinho View Post
    i'm updating the property template class:
    That really doesn't explain things.
    but i need put the 'this' in parameter list
    Which parameter list? You have multiple parameter lists.
    for finish the class. buti don't know do that parameter
    So you write code until you paint yourself into a corner? Aren't you supposed to plan out what you want to do before going ahead and doing it?

    First, this is a runtime value, it isn't a compile-time value. So if the parameter list you're referring to is the template parameter list, there is no way to place this into that list.

    Second, how is this supposed to work?
    Code:
    template <typename Container,const Container *otherClass, 
    //...
    m_cObject= otherClass;
    How do you assign a type to a variable? Does it make sense to do this:
    Code:
    int x;
    x = int; //????????
    ?
    That is basically what your code is doing.

    Third, you're doing all of this template code, but you ignore one of the simplest of C++ idioms -- the initialization list.

    Instead of this:
    Code:
     property()
     {
          m_cObject = NULL;//error:(
          Set = NULL;
          Get = NULL;
    }
    Do this:
    Code:
     property() : m_cObject(NULL), Set(NULL), Get(NULL) {}
    i want, in porperty2, declare a property using a single code line. that's why i'm doing these
    Well, there is no need to ask a question if you know what you want to do. I certainly don't understand what concept you're trying to achieve.

    How about explaining what it is you want to do, without all of the template jargon and code? Then on a high-level explain how a user of this class is supposed to use it easily. Then maybe you will get suggestions on a design-level as to what you want to achieve.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; September 26th, 2013 at 02:04 PM.

  7. #7
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: templates - how define a parameter for recive a function name?

    looking at the code...
    I'm getting the impression you're trying to 'enforce' a getter and setter on a class via the template, that's going about it the wrong way.

    A more logical solution would be to either (in order of what seems most appropriate to me at this time)
    * assume that the template class has a Get() and Set() member that need to conform to the assumptions made in your template. And simply use that get/set in the class template
    * or you have a Get and Set template function you call which can then be specialised for the type you want. (potentially even by defaulting to the above)
    * you use a predicate
    * or you have a dynamic bind between template and the type.


    In a C++ solution. If you're exposing raw pointers via an interface then there's probably a better way to achieve the same.
    there is very little use to ever use 'function pointers', there are "better ways" in C++.

    there's Always exceptions to any rule, but well designed C++ classes/templates don't typically expose pointers, and certainly not function pointers. Using pointers inside class member code is ok, but even there, you can often find a "better" solution.

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: templates - how define a parameter for recive a function name?

    I will try to give an example of OReuben's first point. I can be corrected if it doesn't convey what is being stated:
    Code:
    #include <iostream>
    #include <string>
    #include <assert.h>
    
    template <typename GetterSetter> 
    class property
    {
       GetterSetter m_GetterSetter;
    
       public:
            typename GetterSetter::value_type Get() const
            { 
                assert(GetterSetter::get_defined);
                return m_GetterSetter.Get(); 
            }
            
            void Set(typename GetterSetter::value_type v) 
            { 
                assert(GetterSetter::set_defined);
                m_GetterSetter.Set(v); 
            }
    };
    
    // This basic getter/setter requires default constructable type T to
    // compile
    template <typename T, bool isGettable=true, bool isSettable=true>
    struct BasicGetterSetter
    {
        // requirements for the property template to accept this type
        typedef T value_type;
        enum {get_defined=isGettable?1:0};
        enum {set_defined=isSettable?1:0};
        value_type Get() const { return m_var; }
        void Set(value_type var) { m_var = var; }
    
        private:
            value_type m_var;
    };
    
    using namespace std;
    
    int main()
    {
       // Try an integer    
       property<BasicGetterSetter<int> > pr;
       pr.Set(10);
       cout << pr.Get() << endl;
       
       // Now do a string
       property<BasicGetterSetter<std::string> > prString;
       prString.Set("Hello World");
       cout << prString.Get() << endl;
    }
    You see that the output is 10 and "Hello World".

    The above isn't even the greatest of code (for example, reference type can be used, for those types that should be passed as reference to the Set function, or you can break up the Get/Set into two separate template types, etc.), but it illustrates the point (again, I can be corrected if it doesn't). You could probably break it down so that the "assert" need not be a runtime check, but a compile-time check using static_assert (the property class then needs to be broken down further, but I didn't want to make it overly complex).

    Basically, the property template class doesn't care what you pass to it, as long as whatever it is has an accessible "Get" and "Set" functions, has an accessible "typedef" of value_type that returns the value type, and some sort of definition for "set_defined" and "get_defined". So you can create anything simple, or super complex, as long as it has the "pattern" that the property template requires.

    See how you don't need function pointers, or anything so complex that you're doing now? I don't know if it satisfies your "1 line only" requirement, but it seems close enough.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; September 28th, 2013 at 12:21 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured