Archived

This topic is now archived and is closed to further replies.

Array class

This topic is 5271 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

Hi! What array classes are you using in your projects? Is there are good middleware? As far as i have seen boost::array is only for arrays with fixed size. I need an array class which i can resize at every point. Thanks, Christian

Share this post


Link to post
Share on other sites
quote:
Original post by Austrian Coder
What array classes are you using in your projects?

std::vector.
quote:

Is there are good middleware?

Middleware?

Share this post


Link to post
Share on other sites
Are you using the pure std::vector or have you a little helper class to work easier with std::vector?

Midleware: Libs, sources, so you must not reinvent the wheel (like we are saying here in Austria). So you save a lot of coding time with stuff like arrays,....

Share this post


Link to post
Share on other sites
Uhm... std::vector is an oo-wrapper for arrays, and should be fairly easy to use already? I don''t see a reason to wrap it, unless you want to provide some functionality std::vector alone doesn''t offer.

Share this post


Link to post
Share on other sites
quote:
Original post by Austrian Coder
Are you using the pure std::vector or have you a little helper class to work easier with std::vector?

That has the feel of a trick question. I often wrap low-level concerns such as containers into higher-level abstractions, but you asked about an array class which can be dynamically resizeable. std::vector is such a class.
quote:

Midleware: Libs, sources, so you must not reinvent the wheel (like we are saying here in Austria).

That would be `third-party libraries''. Middleware means something different.

Share this post


Link to post
Share on other sites
quote:
Original post by Austrian Coder
What does Middleware mean?

It usually refers to some form of s/w intermediary for two or more processes. Examples include CORBA and MQ-Series.

Share this post


Link to post
Share on other sites
Nope! Qoute form the news post:

"This anticipated physics middleware has been developed during the last two years to be the most stable and intuitive solution on the market, and at the same time providing unmatched extendibility towards the expert user."

So middleware is the same as third-party libraries!

Share this post


Link to post
Share on other sites
I don''t think their use of ''middleware'' is really accurate. Seems like ''middleware'' is increasingly a buzzword companies throw around because it sounds sexier than ''API'' or ''library.''

Share this post


Link to post
Share on other sites
quote:
Original post by Austrian Coder
Nope! Qoute form the news post:

"This anticipated physics middleware has been developed during the last two years to be the most stable and intuitive solution on the market, and at the same time providing unmatched extendibility towards the expert user."

So middleware is the same as third-party libraries!


The software mentioned in the news post IS middleware AND a third-party library (it goes between a basic game engine, and the top-level application). Just because this particular piece of middleware is third party, doesn''t mean that every third party library is middleware.

Some birds fly. Does that mean that anything that flies is a bird?


How appropriate. You fight like a cow.

Share this post


Link to post
Share on other sites
quote:
Original post by Austrian Coder
Are you using the pure std::vector or have you a little helper class to work easier with std::vector?
What do you feel isn''t easy about std::vector?




How appropriate. You fight like a cow.

Share this post


Link to post
Share on other sites
std::vector is easy to use.

I am thinking in generally about other peoples, beginners, who dont know how to use the std::vector.

So i have written a little array class:


template <class T>
class Array
{
private:
vector<T> m_Array;

public:
Array() {}
~Array() { m_Array.clear(); }

finline vector<T> GetSTLVector() const { return m_Array; }
finline int Size() { return m_Array.size(); }
finline void Resize(int new_size) { m_Array.resize(new_size); }
finline void Clear() { m_Array.clear(); }
finline void Insert(const T& element) { m_Array.push_back(element); }
finline void PopBack() { m_Array.pop_back(); }
finline T Back() const { return m_Array.back(); }
finline T Front() const { return m_Array.front(); }

// delete item at index

finline void Remove(int index)
{
assert(index >= 0 && index <= m_Array.size());

m_Array.erase(m_Array.begin() + index);
}

// search an element

finline int Find(const T& member)
{
for (int i = 0; i < m_Array.size(); ++i)
{
if(m_Array[i] == member)
return i;
}

return -1;
}

// some operators

finline T& operator[] (int index)
{
// index cannot be less than 0 and has to be less than a_size

assert(index >= 0);
assert(index < m_Array.size());

if (index > 0 || index <= m_Array.size())
return m_Array[index];

// bad solution!

// I donkt know who to return

// a 0.

// return (T&)0; - dosent work

return m_Array[-1];
}

// copy operator

inline Array<T>& operator = (Array<T> array)
{
// delete the old array

m_Array.clear();

// copy all elements

for (int i = 0; i < array.Size(); ++i)
{
m_Array.push_back(array[i]);
}

return *this;
}


// comparisons

template<class T>
bool operator == (const Array<T>& x)
{
return std::equal(m_Array.begin(), m_Array.end(), x.GetSTLVector().begin());
}

template<class T>
bool operator < (const Array<T>& x)
{
return std::lexicographical_compare(m_Array.begin(),m_Array.end(),x.GetSTLVector().begin(),x.GetSTLVector().end());
}

template<class T>

bool operator != (const Array<T>& x)
{
return !(m_Array.GetSTLVector() == x.GetSTLVector());
}

template<class T>
bool operator > (const Array<T>& x)
{
return m_Array.GetSTLVector()<x.GetSTLVector();
}

template<class T>
bool operator<= (const Array<T>& x)
{
return !(m_Array.GetSTLVector()<x.GetSTLVector());
}

template<class T>
bool operator>= (const Array<T>& x)
{
return !(x.GetSTLVector()<m_Array.GetSTLVector());
}
};


It adds some stuff to the generall std::vector, i think. Will this litte ''helper'' be as fast as the pure std::vector?

Oh i forgot: #define finline __forceinline

Share this post


Link to post
Share on other sites
Errrrm.


Well, your wrapper class should be plenty fast, I suppose, given that it doesn''t actually DO anything other than wrap vector calls and can thus be optimized away. Your operator overloads might be slower than the operators built into STL.... or were you not aware that all those operators are ALREADY overloaded for vector? Same deal with find().

Here''s your vector class, rewritten in preprocessor form.


#define Array vector
#define Size size
#define Resize resize
#define Clear clear
#define Insert push_back
#define PopBack pop_back
#define Back back
#define Front front
#define Remove erase
#define Find find

There ya go. No charge for this "middleware". Now, what was the point of this whole exercise? Is "PopBack" somehow easier to learn than "pop_back"?


How appropriate. You fight like a cow.

Share this post


Link to post
Share on other sites
Hiding the details of a vector isn''t going to help beginners. Better to just start working with it first hand. People don''t learn STL for awhile anyway -- it isn''t really for beginners. I would have the students write their own array class to learn about it.

Share this post


Link to post
Share on other sites
quote:
Original post by Austrian Coder
I am thinking in generally about other peoples, beginners, who dont know how to use the std::vector.

So i have written a little array class:


template <class T>
class Array
{
private:
vector<T> m_Array;

public:
Array() {}
~Array() { m_Array.clear(); }

finline vector<T> GetSTLVector() const { return m_Array; }
finline int Size() { return m_Array.size(); }
finline void Resize(int new_size) { m_Array.resize(new_size); }
finline void Clear() { m_Array.clear(); }
finline void Insert(const T& element) { m_Array.push_back(element); }
finline void PopBack() { m_Array.pop_back(); }
finline T Back() const { return m_Array.back(); }
finline T Front() const { return m_Array.front(); }

// delete item at index

finline void Remove(int index)
{
assert(index >= 0 && index <= m_Array.size());

m_Array.erase(m_Array.begin() + index);
}

// search an element

finline int Find(const T& member)
{
for (int i = 0; i < m_Array.size(); ++i)
{
if(m_Array[i] == member)
return i;
}

return -1;
}

// some operators

finline T& operator[] (int index)
{
// index cannot be less than 0 and has to be less than a_size

assert(index >= 0);
assert(index < m_Array.size());

if (index > 0 || index <= m_Array.size())
return m_Array[index];

// bad solution!

// I donkt know who to return

// a 0.

// return (T&)0; - dosent work

return m_Array[-1];
}

// copy operator

inline Array<T>& operator = (Array<T> array)
{
// delete the old array

m_Array.clear();

// copy all elements

for (int i = 0; i < array.Size(); ++i)
{
m_Array.push_back(array[i]);
}

return *this;
}


// comparisons

template<class T>
bool operator == (const Array<T>& x)
{
return std::equal(m_Array.begin(), m_Array.end(), x.GetSTLVector().begin());
}

template<class T>
bool operator < (const Array<T>& x)
{
return std::lexicographical_compare(m_Array.begin(),m_Array.end(),x.GetSTLVector().begin(),x.GetSTLVector().end());
}

template<class T>

bool operator != (const Array<T>& x)
{
return !(m_Array.GetSTLVector() == x.GetSTLVector());
}

template<class T>
bool operator > (const Array<T>& x)
{
return m_Array.GetSTLVector()<x.GetSTLVector();
}

template<class T>
bool operator<= (const Array<T>& x)
{
return !(m_Array.GetSTLVector()<x.GetSTLVector());
}

template<class T>
bool operator>= (const Array<T>& x)
{
return !(x.GetSTLVector()<m_Array.GetSTLVector());
}
};



Your Array class does not add anything to std::vector that isn't already present.
quote:

It adds some stuff to the generall std::vector, i think.

It bloats the interface by adding operations which don't need to be members (e.g. Find, Remove). It also confuses the issue by adding in operations which won't always be well-defined within the problem domain, so will be rendered meaningless as part of an Array class. For instance, what does operator< mean for an Array of non-comparable elements?
quote:

Oh i forgot: #define finline __forceinline

They're already inline without specifying inline. You cannot force inlining as the compiler is free to ignore you.

[edited by - SabreMan on July 10, 2003 6:59:54 AM]

Share this post


Link to post
Share on other sites
So... i have deleted my array class and i will use now pure std::vector.

@SabreMan:

From MSDN:
The __forceinline keyword instructs the compiler to inline the function without performing any cost/benefit analysis. The programmer must exercise good judgement in using this keyword. Indiscriminate use of __forceinline can result in larger, and sometimes even slower, code.

"They''re already inline without specifying inline. You cannot force inlining as the compiler is free to ignore you."

Why are they already inlined without specifying inline?

Share this post


Link to post
Share on other sites
quote:
Original post by Austrian Coder
From MSDN:
The __forceinline keyword instructs the compiler to inline the function without performing any cost/benefit analysis. The programmer must exercise good judgement in using this keyword. Indiscriminate use of __forceinline can result in larger, and sometimes even slower, code.



If you look carefully, it says ''Microsoft Specific''. C++ compilers in general are completely free to ignore inline and register keywords. There is a reason why they are called compiler hints.

quote:

Why are they already inlined without specifying inline?



You declared them in the body of the class.



[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]

Share this post


Link to post
Share on other sites
__forceinline is pretty much never a good idea. Ya see, inlining is not always a good idea. It bloats code, which can cause instruction cache misses. The compiler is very good at determining when this is good and when it is bad. And if you make it inline something when it really shouldn''t be inlined, you''re only hurting yourself.

Share this post


Link to post
Share on other sites
I use __forceinline when the function is very short (up to 3-4 lines) or when i have this situation:

class X
{
private:
int a;

public:
__forceinline void Seta(int v) { a = v; }
__forceinline int Geta() { return a; }
}

So i think the using of __forceinline is in this case ok.

Share this post


Link to post
Share on other sites
Its redundant in that case usually. The definition is right there so it is free to inject it where you call the methods if it feels it needs to. And in that case the normal inline keyword is fine. Your compiler knows your code better than you do...thats its job.

I stay away from proprietary extensions as much as possible. Inlining is something to be done at the very end anyway. I''d keep definitions for everything out of the H file so they can''t get inlined at all.

More Effective C++ has some eye-opening sections on why inlining isn''t always a good thing.

Share this post


Link to post
Share on other sites
Aren''t member functions defined in the class body always inlined? Or else, in which compilation unit would the compiler put it?

Cédric

Share this post


Link to post
Share on other sites