Sign in to follow this  

[C++] Array definition in function parameter

This topic is 3042 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have an enum ie.
enum FrameType
{
	FRAME_LEFT,
	FRAME_RIGHT,
	FRAME_UP,
	FRAME_DOWN,
	FRAME_DEAD
};
This enum describes a single frame of animation in a sprite sheet. In my CSprite's class contructor it takes an array of FrameType to describe what each frame of animation is. ie. CSprite(FrameType frameType[]) What I want to do is be able to describe what each frame is in the contructor by placing a list of the frame values. In C# it's easy to do this like so. Eg. m_sprite[0] = new CSprite(new FrameType { FRAME_LEFT, FRAME_RIGHT ... }); Is there a way to do this in C++?

Share this post


Link to post
Share on other sites
You can do it in C++0x, but not under the current rules. Why not make it a bitfield enum (akin to C# [Flags] attribute) instead of an array?


enum FrameType
{
FRAME_LEFT = 0x1,
FRAME_RIGHT = 0x2,
FRAME_UP = 0x4,
FRAME_DOWN = 0x8,
FRAME_DEAD = 0x10
};

class CSprite
{
CSprite(FrameType type);
};

m_sprite[0] = new CSprite(FRAME_LEFT | FRAME_RIGHT);


Share this post


Link to post
Share on other sites
Flags wouldn't help because I need to describe an array of frames that are in the sprite sheet. Using bits would not allow me to know what order the frames are in and where they are located in the array. Some sprites sheets have extra frames and some have missing frames and the order can be different for each one.

There are things I'm sorely missing from C# at the moment! If anyone else has a suggestion feel free to drop it on me.

Share this post


Link to post
Share on other sites
If you're describing an array of frames, is there no way to have the flag be a member of the Frame object? That way instead of an array of FrameTypes, you have an array of Frames.

Share this post


Link to post
Share on other sites
Create a struct or class that contains the frame order and pass a reference or pointer to the Sprite constructor.

Several Sprite instances will likely use the same animation data, so there's no need for each Sprite to contain a copy of that data anyway.

Share this post


Link to post
Share on other sites
Quote:
Original post by Headkaze
Eg. m_sprite[0] = new CSprite(new FrameType { FRAME_LEFT, FRAME_RIGHT ... });

Is there a way to do this in C++?

There is no way to do that in C++. In C++, an array passed as an argument to a function degenerates to a pointer to the first elemnet of the array. In the current standard C++ there is no way to explicitly initialize an array constructed on the free store (ie. using the new[] operator), or to create a temporary explictly initialized array in automatic storage.

To do what you;re suggesting, you have to create the array, explicitly initialize it, then pass it to your CSprite constructor. You may create and initialize the array in static storage if the same set of FrameTypes gets reused frequently so that it only get constructed and initialized once.

Share this post


Link to post
Share on other sites
struct Helper {
Helper(FrameType ft) {
frames.push_back(ft);
}
Helper & operator()(FrameType ft) {
frames.push_back(ft);
return *this;
}

const std::vector<FrameType> & frames() const {
return frames;
}
private:
std::vector<FrameType> frames;
};

class Sprite {
std::vector<FrameType> frames;
Sprite(const Helper & h)
: frames(h.frames())
{}
};

...

Sprite s(Helper(FRAME_LEFT)(FRAME_RIGHT)(FRAME_DEAD));

Share this post


Link to post
Share on other sites
Slightly more array'ish version [smile]

Helper:
#include <vector>
#include <iostream>

enum FrameType {
FRAME_LEFT,
FRAME_RIGHT,
FRAME_UP,
FRAME_DOWN,
FRAME_DEAD
};

struct FrameTypeArray {

FrameTypeArray& operator = (FrameTypeArray const &rhs) {
types = rhs.types;
return *this;
}

FrameTypeArray (FrameType type) {
types.push_back (type);
}

FrameTypeArray (FrameTypeArray const &rhs)
: types (rhs.types)
{}

FrameTypeArray () {}

FrameTypeArray (FrameType lhs, FrameType rhs) {
types.push_back (lhs);
types.push_back (rhs);
}

FrameTypeArray (FrameTypeArray lhs, FrameType rhs) {
types = lhs.types;
types.push_back (rhs);
}

operator FrameType* () const {
FrameType* ret = new FrameType [types.size()];
for (size_t i=0; i<types.size(); ++i)
ret [i] = types [i];
return ret;
}

operator std::vector<FrameType> () const {
return types;
}

friend FrameTypeArray operator , (FrameType lhs, FrameType rhs) {
return FrameTypeArray (lhs, rhs);
}

friend FrameTypeArray operator , (FrameTypeArray lhs, FrameType rhs) {
return FrameTypeArray (lhs, rhs);
}

private:
std::vector<FrameType> types;
};


Dumpery:
namespace std {
ostream& operator<< (ostream& out, FrameType val) {
switch (val) {
case FRAME_LEFT: out << "FRAME_LEFT"; break;
case FRAME_RIGHT: out << "FRAME_RIGHT"; break;
case FRAME_UP: out << "FRAME_UP"; break;
case FRAME_DOWN: out << "FRAME_DOWN"; break;
case FRAME_DEAD: out << "FRAME_DEAD"; break;
};
return out;
}
}


Usage:
int main () {
// Native array.
{
FrameType *types = (FRAME_DOWN, FRAME_UP, FRAME_LEFT, FRAME_LEFT);
for (int i=0; i<4; ++i)
std::cout << types [i] << ' ';
std::cout << std::endl;
delete [] types;
}

// STL vector.
{
std::vector<FrameType> types = (FRAME_DOWN, FRAME_UP, FRAME_LEFT, FRAME_LEFT);
for (std::vector<FrameType>::const_iterator it = types.begin();
it != types.end();
++it
)
std::cout << *it << ' ';
std::cout << std::endl;
}
}


Need to write FrameTypeArray(xxx) for less than 3 arguments, though.

Share this post


Link to post
Share on other sites

This topic is 3042 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this