#include <iostream>
using namespace std;
// Array Template
template <class DataType>
class Array {
public:
DataType * m_array;
int m_size;
// Constructor. Takes the size of the array to create
// as an argument.
Array( int p_size )
{
// Create an array of DataType with given size.
m_array = new DataType[p_size];
m_size = p_size;
}
// Destructor - Checks to see if the array has
// been initialized and if so, destroys it.
~Array()
{
if ( m_array != 0 ) {
delete[] m_array;
}
}
// resize - Resizes the current array to
// p_size.
void resize( int p_size )
{
// Create a temporary array
DataType * tempArray = new DataType[p_size];
// Check to make sure that the temp array
// was initialized okay.
if ( newArray != 0 ) {
// Determine if the new size of the array
// is larger or smaller than the old size.
// If it is smaller, all data in the old array
// past that point will be lost. If it is larger
// we can only copy over the data that was
// in the original array.
int min = p_size < m_size ? p_size : m_size;
int index;
// Copy the contents of the old array into
// the temp array.
for ( index = 0; index < min; index++ ) {
newArray[index] = m_array[index];
}
// Update the size of the new array.
m_size = p_size;
// Delete the old array.
if ( m_array != 0 ) {
delete[] m_array;
}
// Set the old array to the new array
// and we are done.
m_array = newArray;
}
// Overload the [] operator so we can use
// this array just like any other array.
DataType& operator[](int p_index)
{
return m_array[p_index];
}
// Overload the conversion operator so
// we can seamlessly pass this into a
// function.
operator Array::DataType* ()
{
// Simply return a pointer to the array.
return m_array;
}
}
};
int main()
{
Array<int> intArray(10);
intArray[5] = 6;
cout << intArray[5] << endl;
return 0;
}
🔒 Locked
Overloading []
Advertisement
Original Post
I can't seem to get the overloading of the [] operator for this Array Template to work. I keep getting this error: error C2676: binary '[' : 'Array' does not define this operator or a conversion to a type acceptable to the predefined operator with [ DataType=int ] Here's my code: I am using Visual C++ 2005 Express as well. I've tried fooling around with it a couple of different ways but I just seem to be making it worse. Thanks for the help.
I don't know.. I've seen an example do it the same way. I also tried doing it the way it's done in the C++ complete reference, which gives me this:
But this gives me even more errors:
c:\projects\cpp\lab\lab\main.cpp(94) : error C2143: syntax error : missing ';' before '&'
c:\projects\cpp\lab\lab\main.cpp(94) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
c:\projects\cpp\lab\lab\main.cpp(94) : error C2955: 'Array' : use of class template requires template argument list
c:\projects\cpp\lab\lab\main.cpp(92) : see declaration of 'Array'
c:\projects\cpp\lab\lab\main.cpp(94) : error C2039: '[]' : is not a member of 'Array'
c:\projects\cpp\lab\lab\main.cpp(92) : see declaration of 'Array'
c:\projects\cpp\lab\lab\main.cpp(94) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
c:\projects\cpp\lab\lab\main.cpp(95) : error C2065: 'm_index' : undeclared identifier
c:\projects\cpp\lab\lab\main.cpp(95) : warning C4508: '[]' : function should return a value; 'void' return type assumed
Do I maybe have to do something different since I'm using a templated class?
// Method declaration inside classDataType& operator[](int p_index);// Method body outside classDataType& Array::operator[](int p_index) { return m_index[p_index];}But this gives me even more errors:
c:\projects\cpp\lab\lab\main.cpp(94) : error C2143: syntax error : missing ';' before '&'
c:\projects\cpp\lab\lab\main.cpp(94) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
c:\projects\cpp\lab\lab\main.cpp(94) : error C2955: 'Array' : use of class template requires template argument list
c:\projects\cpp\lab\lab\main.cpp(92) : see declaration of 'Array'
c:\projects\cpp\lab\lab\main.cpp(94) : error C2039: '[]' : is not a member of 'Array'
c:\projects\cpp\lab\lab\main.cpp(92) : see declaration of 'Array'
c:\projects\cpp\lab\lab\main.cpp(94) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
c:\projects\cpp\lab\lab\main.cpp(95) : error C2065: 'm_index' : undeclared identifier
c:\projects\cpp\lab\lab\main.cpp(95) : warning C4508: '[]' : function should return a value; 'void' return type assumed
Do I maybe have to do something different since I'm using a templated class?
As sneftel said your code doesn't work because you're declaring your operators within a function. You need to move the function's (resize()) closing brace:
This compiles and works correctly (I'm using MSVS .NET 2K3)
#include <vector>#include <string>#include <iostream>#include "FackinAround.h"#include <iostream>using namespace std;// Array Templatetemplate <class DataType>class Array {public: DataType * m_array; int m_size; // Constructor. Takes the size of the array to create // as an argument. Array( int p_size ) { // Create an array of DataType with given size. m_array = new DataType[p_size]; m_size = p_size; } // Destructor - Checks to see if the array has // been initialized and if so, destroys it. ~Array() { if ( m_array != 0 ) { delete[] m_array; } } // resize - Resizes the current array to // p_size. void resize( int p_size ) { // Create a temporary array DataType * tempArray = new DataType[p_size]; // Check to make sure that the temp array // was initialized okay. if ( newArray != 0 ) { // Determine if the new size of the array // is larger or smaller than the old size. // If it is smaller, all data in the old array // past that point will be lost. If it is larger // we can only copy over the data that was // in the original array. int min = p_size < m_size ? p_size : m_size; int index; // Copy the contents of the old array into // the temp array. for ( index = 0; index < min; index++ ) { newArray[index] = m_array[index]; } // Update the size of the new array. m_size = p_size; // Delete the old array. if ( m_array != 0 ) { delete[] m_array; } // Set the old array to the new array // and we are done. m_array = newArray; } }// now its here. // Overload the [] operator so we can use // this array just like any other array. DataType& operator[](int p_index) { return m_array[p_index]; } // Overload the conversion operator so // we can seamlessly pass this into a // function. // I also had to remove Array:: from below: operator DataType*() { // Simply return a pointer to the array. return m_array; } //} was here};int main(){ Array<int> intArray(10); intArray[5] = 6; cout << intArray[5] << endl; return 0;}This compiles and works correctly (I'm using MSVS .NET 2K3)
Smacks head than proceeds to beat head against desk...
That was easily one of the most stupid errors I've made in a while.. I didn't even completely realize what Sneftel was telling me...
Thanks for making me realize this. I probably would have been messing with it for a while..
That was easily one of the most stupid errors I've made in a while.. I didn't even completely realize what Sneftel was telling me...
Thanks for making me realize this. I probably would have been messing with it for a while..
Use the explicit keyword to prevent the compiler from using conversions implicitly (unless that's what you want, of course). For example, with you're code atm you could do the following:
This would create a new array with 6 elements and you'll loose all of it's previous contents (probably resulting from a typo where you forgot the index).
This is how you'd use the explicit keyword:
Why are m_array and and m_size public? These members should be private.
There's no need to check that m_array!=0 before delete'ing it, deleting a NULL pointer is perfectly safe and does nothing.
Provide const versions of the operator[] and operator Array::DataType* functions.
....and I'll be good and not mention anything about exception safetly and using std::vector [smile]
int main(){ Array<int> intArray(10); intArray = 6; cout << intArray.size() << endl; return 0;}This would create a new array with 6 elements and you'll loose all of it's previous contents (probably resulting from a typo where you forgot the index).
This is how you'd use the explicit keyword:
template<class DataType>class Array {public: //... explicit Array( int p_size ) { ... } //... explicit operator Array::DataType* () { ... }};Why are m_array and and m_size public? These members should be private.
There's no need to check that m_array!=0 before delete'ing it, deleting a NULL pointer is perfectly safe and does nothing.
Provide const versions of the operator[] and operator Array::DataType* functions.
....and I'll be good and not mention anything about exception safetly and using std::vector [smile]
Quote:
Provide const versions of the operator[] and operator Array::DataType* functions.
Could you explain the reasoning behind having these methods const? Is it because they don't change anything within the class? Should there only be const methods of these?
Quote:
....and I'll be good and not mention anything about exception safetly and using std::vector
This is the kind of advice I'm really interested in..I'm going to start another post around this subject since this is starting to go a little off the original topic, and I think more people would benefit from this.
Here's a link to why it should be const:
http://www.parashift.com/c++-faq-lite/const-correctness.html
It really makes catching mistakes/errors a lot easier when you use it correctly I've found. At first I disliked it, I still make a class, get it working then go back and make it const correct (most times within minutes, shouldn't take long to get a class up and running).
http://www.parashift.com/c++-faq-lite/const-correctness.html
It really makes catching mistakes/errors a lot easier when you use it correctly I've found. At first I disliked it, I still make a class, get it working then go back and make it const correct (most times within minutes, shouldn't take long to get a class up and running).
Quote:
Original post by caseyd Quote:
Provide const versions of the operator[] and operator Array::DataType* functions.
Could you explain the reasoning behind having these methods const? Is it because they don't change anything within the class? Should there only be const methods of these?
Let's say for example you're passing an Array
class Renderer{ //... void render(const Array<IRenderable>& vertices);};Now inside your render() function you need to access the individual vertices with operator[], BUT if you don't have a const version of operator[] you won't be able to. Hence, you provide both const and non-const version of operator[].
Quote:[/quote]
Original post by caseyd Quote:
....and I'll be good and not mention anything about exception safetly and using std::vector
This is the kind of advice I'm really interested in..I'm going to start another post around this subject since this is starting to go a little off the original topic, and I think more people would benefit from this.
Fair enough, but be warned that if you *really* want to get into the nitty gritty it can get fairly complicated.
Thanks. I read through the C++ faq on const correctness, I need to read it again though and try out a few things to really get it down. I am already seeing how complicated even something like this can get. It's really great though as going through this stuff is really showing me where I need to improve.
Thanks for all of your replies.
Thanks for all of your replies.
... // resize - Resizes the current array to // p_size. void resize( int p_size ) { // Create a temporary array DataType * tempArray = new DataType[p_size]; // Check to make sure that the temp array // was initialized okay. if ( newArray != 0 ) {Is "newArray" here supposed to be "tempArray"? If so, there is no need to check whether it is 0 - new will either return a pointer to a valid memory allocation or will throw a std::bad_alloc exception.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement