Skip to main content
gamedev.net
🔒 Locked

C++ template member function question...

Started by BeerNutts 11 replies 2.4k views
Original Post
BeerNutts
BeerNutts
I fear I know the answer to this, but I wanted to be sure since I'm still not 100% sure about templates.

I have a class, and I want to be able to store and retrieve some data of any type, but I don't want to have to re-declare my class as a template since this is a minor piece of the class.

So, I'd have this

class MyClass
{
public:
MyClass() {}
~MyClass() {}

template <class T>
void SetData(T &Data);

template <class T>
void GetData(T&Data);

private:
T &mData
}


I'm pretty sure it's not possible to do it the way i want, but are there other options I haven't looked it?

Thanks
My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)
jjd
jjd

I fear I know the answer to this, but I wanted to be sure since I'm still not 100% sure about templates.

I have a class, and I want to be able to store and retrieve some data of any type, but I don't want to have to re-declare my class as a template since this is a minor piece of the class.

So, I'd have this

class MyClass
{
public:
MyClass() {}
~MyClass() {}

template <class T>
void SetData(T &Data);

template <class T>
void GetData(T&Data);

private:
T &mData
}


I'm pretty sure it's not possible to do it the way i want, but are there other options I haven't looked it?

Thanks


You can have member functions that are templatized like that (as long as you include the implementation in the header), but if you want that member variable to be determined by the template type, that requires the class to be templatized.

-Josh
swiftcoder
swiftcoder

I'm pretty sure it's not possible to do it the way i want, but are there other options I haven't looked it?

In general, the fact that you think you need to store data of an arbitrary type, is likely to indicate a gaping whole in your program design.

But if you really, really have to... then don't reinvent the wheel.
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
hkBattousai
hkBattousai

Hello.
You should better write your code as below if you just one to store the date in your class.[size=2]

template <class T>
class MyClass
{
public:
MyClass() {}
~MyClass() {}

void SetData(const T &Data);

void GetData(T &Data) const;

private:
T mData;
};


template <class T>
void MyClass::SetData(const T &Data)
{
mData = Data;
}


template <class T>
void MyClass::GetData(T &Data) const
{
Data = mData
}


EDIT: GetDate() member mustn't be constant. You must fix that mistake in the code above.
BeerNutts
BeerNutts


Hello.
You should better write your code as below if you just one to store the date in your class.[size=2]

template <class T>
class MyClass
{
public:
MyClass() {}
~MyClass() {}

void SetData(const T &Data);

void GetData(T &Data) const;

private:
T mData;
};


template <class T>
void MyClass::SetData(const T &Data)
{
mData = Data;
}


template <class T>
void MyClass::GetData(T &Data) const
{
Data = mData
}



Thanks, but the point was doing that WITHOUT having the class be declared as a template.
My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)
hkBattousai
hkBattousai

Thanks, but the point was doing that WITHOUT having the class be declared as a template.


OK, then. If that was the point, you can use your original code as well.
But, are you sure that you want to save a reference to mData instead of the mData itself?

Also, I see that you defined mData as the T type. But it will give a compiler error since T is not defined inside MyClass. This is a problem you should somehow overcome if you don't want to use a template class.
rip-off
rip-off
Do you actually need to be able to store any type, or just a set of types (typically something like {int, float, string, bool})?

Can you describe what this class is or how it would be used?
kindjie
kindjie
This smells like a design problem, so I'm not recommending you actually do this, but you could just make mData a void*.

Right now, it looks like you're just writing a clumsy wrapper for the C++ type system.
[size="1"]Try GardenMind by Inspirado Games !
All feedback welcome.
[s]
[/s] [size="1"]Twitter: [twitter]Owen_Inspirado[/twitter]
Facebook: Owen Wiggins [size="1"]Goog
BeerNutts
BeerNutts

This smells like a design problem, so I'm not recommending you actually do this, but you could just make mData a void*.

Right now, it looks like you're just writing a clumsy wrapper for the C++ type system.


The class above is just an example, it's actually an Event system, where the client sends an event to a register listener. I was looking at adding a data component to the event.

I currently am using a void*, but I thought a template solution would've been more elegant solution, so I was trying to add it in with out redefining the class.
My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)
swiftcoder
swiftcoder

I'm not recommending you actually do this, but you could just make mData a void*.

I'm going to reiterate this: if you think you need a void * you have a design problem. But if you can't fix your design problem, then boost::any is much preferable to a void * pointer.
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
Washu
Washu

[quote name='kindjie' timestamp='1322863474' post='4889929']
This smells like a design problem, so I'm not recommending you actually do this, but you could just make mData a void*.

Right now, it looks like you're just writing a clumsy wrapper for the C++ type system.


The class above is just an example, it's actually an Event system, where the client sends an event to a register listener. I was looking at adding a data component to the event.

I currently am using a void*, but I thought a template solution would've been more elegant solution, so I was trying to add it in with out redefining the class.
[/quote]

At no point during the invocation of an event system should you NOT know the exact type of the parameters.

A button click event handler will take exactly one type. The instant you introduce the magical void* into things you lose all type safety and introduce significant chance of bugs.

You invoke your event with a PointF, I catch the event and cast the void* I got to a PointI, and blamo bugo. Now I've got to waste MY time debugging and trying to figure out why my PointI has such wonky values, walking the stack trace, only to find out you're using a PointF... "Gee," I say, "it sure would have been nice if this event had just had the signature for a PointF instead of a void*."

Use boost signals/slots, or any of the other existing and very useful signals and slots implementations. That way you can have end to end type safety.
In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
Sudi
Sudi

[quote name='BeerNutts' timestamp='1322864310' post='4889936']
[quote name='kindjie' timestamp='1322863474' post='4889929']
This smells like a design problem, so I'm not recommending you actually do this, but you could just make mData a void*.

Right now, it looks like you're just writing a clumsy wrapper for the C++ type system.


The class above is just an example, it's actually an Event system, where the client sends an event to a register listener. I was looking at adding a data component to the event.

I currently am using a void*, but I thought a template solution would've been more elegant solution, so I was trying to add it in with out redefining the class.
[/quote]

At no point during the invocation of an event system should you NOT know the exact type of the parameters.

A button click event handler will take exactly one type. The instant you introduce the magical void* into things you lose all type safety and introduce significant chance of bugs.

You invoke your event with a PointF, I catch the event and cast the void* I got to a PointI, and blamo bugo. Now I've got to waste MY time debugging and trying to figure out why my PointI has such wonky values, walking the stack trace, only to find out you're using a PointF... "Gee," I say, "it sure would have been nice if this event had just had the signature for a PointF instead of a void*."

Use boost signals/slots, or any of the other existing and very useful signals and slots implementations. That way you can have end to end type safety.
[/quote]

I agree and disagree. Sometimes its more simple to have a universal eventinterface but at the same time typesafety. i managed to get something like that by using an empty eventclass that is subclassed by the correct event and passed to the event manager. the eventmanager then disides whic of it handlers matches the signature of the event and only passes it to those.
BeerNutts
BeerNutts

[quote name='BeerNutts' timestamp='1322864310' post='4889936']
[quote name='kindjie' timestamp='1322863474' post='4889929']
This smells like a design problem, so I'm not recommending you actually do this, but you could just make mData a void*.

Right now, it looks like you're just writing a clumsy wrapper for the C++ type system.


The class above is just an example, it's actually an Event system, where the client sends an event to a register listener. I was looking at adding a data component to the event.

I currently am using a void*, but I thought a template solution would've been more elegant solution, so I was trying to add it in with out redefining the class.
[/quote]

At no point during the invocation of an event system should you NOT know the exact type of the parameters.

A button click event handler will take exactly one type. The instant you introduce the magical void* into things you lose all type safety and introduce significant chance of bugs.

You invoke your event with a PointF, I catch the event and cast the void* I got to a PointI, and blamo bugo. Now I've got to waste MY time debugging and trying to figure out why my PointI has such wonky values, walking the stack trace, only to find out you're using a PointF... "Gee," I say, "it sure would have been nice if this event had just had the signature for a PointF instead of a void*."

Use boost signals/slots, or any of the other existing and very useful signals and slots implementations. That way you can have end to end type safety.
[/quote]

I'd never suggest to anyone to use void * as I do; but, fortunately, this isn't my 1st rodeo.
My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.