-
September 26th, 2013, 05:31 AM
#1
templates - how define a parameter for recive a function name?
can i do a template class parameter for recive a function name?
-
September 26th, 2013, 08:43 AM
#2
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.
-
September 26th, 2013, 08:50 AM
#3
Re: templates - how define a parameter for recive a function name?
Originally Posted by OReubens
"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)?
-
September 26th, 2013, 10:15 AM
#4
Re: templates - how define a parameter for recive a function name?
What is the bigger picture of what you are trying to do?
-
September 26th, 2013, 10:48 AM
#5
Re: templates - how define a parameter for recive a function name?
Originally Posted by laserlight
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.
-
September 26th, 2013, 01:14 PM
#6
Re: templates - how define a parameter for recive a function name?
Originally Posted by Cambalinho
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.
-
September 27th, 2013, 07:09 AM
#7
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.
-
September 27th, 2013, 06:31 PM
#8
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|