[C++] Array definition in function parameter

Started by
6 comments, last by phresnel 14 years, 8 months ago
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++?
Advertisement
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);
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.
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.
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.
Create-ivity - a game development blog Mouseover for more information.
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.

Stephen M. Webb
Professional Free Software Developer

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));
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  = types ;                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  << ' ';                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.

This topic is closed to new replies.

Advertisement