K
k04jg02
I was thinking that it would be cool if a programming language could
implement an array type in its standard library rather than depending
on arrays being a builtin type. I wondered if C++ could do this.
Obviously, writing a class that just used a C array under the hood
would be cheating. As would simply allocating a big chunk of memory on
the heap -- for it to be a true equivalent of a C array it should be
allocate memory on the stack.
I came up with the following compileable solution but I'm not sure it
will always work. I don't know if the standard somehow mandates that
the 'mem' members will be contiguous. I figured out a way to make it
work on some nonoptimizing compilers (see comment below) but I'm
curious if anyone has a way to make it even more safe. Or an
alternative way altogether.
#include <cstdlib>
#include <iostream>
using namespace std;
template<class T, int n>
class Array : public Array<T, n-1>
{
public:
T& operator[](int i);
protected:
T mem;
};
//// Works on gcc 3.4 but probably
//// breaks on nonoptimizing compilers
//template<class T, int n>
//T& Array<T, n>:perator[](int i)
//{
// return (T&)(*((int*)(this) + i));
//}
// This definition is better because it
// will work on compilers that don't
// optimize away Array<T, 0> occupying
// a leading byte.
// See:
// http://www.research.att.com/~bs/bs_faq2.html#sizeof-empty
template<class T, int n>
T& Array<T, n>:perator[](int i)
{
// Should be able to just use line below
// but some compilers are stupid
// return *(&(Array<T, 1>::mem) + i);
int& x = Array<T, 1>::mem;
return *(&x + i);
}
template<class T>
class Array<T, 0> {};
int main(int argc, char *argv[])
{
Array<int, 5> x;
cout << sizeof(Array<int, 5>) << endl; // 20 as expected
x[0] = 9;
x[1] = 8;
x[2] = 4;
x[3] = 2;
x[4] = 5;
// Prints correctly
cout << x[0] << x[1] << x[2] << x[3] << x[4] << endl;
return 0;
}
implement an array type in its standard library rather than depending
on arrays being a builtin type. I wondered if C++ could do this.
Obviously, writing a class that just used a C array under the hood
would be cheating. As would simply allocating a big chunk of memory on
the heap -- for it to be a true equivalent of a C array it should be
allocate memory on the stack.
I came up with the following compileable solution but I'm not sure it
will always work. I don't know if the standard somehow mandates that
the 'mem' members will be contiguous. I figured out a way to make it
work on some nonoptimizing compilers (see comment below) but I'm
curious if anyone has a way to make it even more safe. Or an
alternative way altogether.
#include <cstdlib>
#include <iostream>
using namespace std;
template<class T, int n>
class Array : public Array<T, n-1>
{
public:
T& operator[](int i);
protected:
T mem;
};
//// Works on gcc 3.4 but probably
//// breaks on nonoptimizing compilers
//template<class T, int n>
//T& Array<T, n>:perator[](int i)
//{
// return (T&)(*((int*)(this) + i));
//}
// This definition is better because it
// will work on compilers that don't
// optimize away Array<T, 0> occupying
// a leading byte.
// See:
// http://www.research.att.com/~bs/bs_faq2.html#sizeof-empty
template<class T, int n>
T& Array<T, n>:perator[](int i)
{
// Should be able to just use line below
// but some compilers are stupid
// return *(&(Array<T, 1>::mem) + i);
int& x = Array<T, 1>::mem;
return *(&x + i);
}
template<class T>
class Array<T, 0> {};
int main(int argc, char *argv[])
{
Array<int, 5> x;
cout << sizeof(Array<int, 5>) << endl; // 20 as expected
x[0] = 9;
x[1] = 8;
x[2] = 4;
x[3] = 2;
x[4] = 5;
// Prints correctly
cout << x[0] << x[1] << x[2] << x[3] << x[4] << endl;
return 0;
}