real_array: new class template

Hi to everyone,
I've created a new class template to replace arrays (it's only an exercise, nothing serious). The main difference is in the indexing (it's weird and unuseful, i know, but I'm just a student): to access at the n-th element you have to use [n] or .at(n) instead of n-1.

1
2
3
jfet::real_array<int> my_array {1,2,3,4,5,6};
std::cout << my_array[2] << " It will print 2 instead of 3" << std::endl;
std::cout << my_array.at(4) << " It will print 4 instead of 5" << std::endl;


I'm looking for new ideas to implement for a better use of this weird class template and bad-practices to avoid / best-practices to use.

You can see the code here https://github.com/jfet97/real_array and read the wiki here for more explanations https://github.com/jfet97/real_array/wiki
Last edited on
In general I think it's best practice to use zero-based indexing because that's what C++ programmers are used to and expect. Anything else is more likely to lead to mistakes.

Why are the access functions silently returning a value when the index is too small (=0) when it throws an exception for index is too large? Wouldn't it be more consistent to always throw an exception when the index is out of bounds?

operator[] and at() are doing the same thing so to reduce code repetition you could make one call the other. The code for the const and non-const versions of these functions are also the same but you can't simply use the const version to implement the non-const version (or vice versa) because the return type is not the same. In this case the function is relatively small so it's probably OK to repeat the code but if don't want to repeat the code at all you could make it work by using const_cast.

1
2
3
4
template <typename T>
T& real_array<T>::at(size_t _n) {
    return const_cast<T&>(static_cast<const real_array<T>*>(this)->at(_n));
}

Last edited on
I also found these minor problems:

In the initializer_list constructor you are trying to move from the initializer_list but that will still copy because the initializer_list only provides const access to the values.

In the const version of back() you have written -size instead of _size.

In the copy assignment operator you seem to assume the size is already at least as big as for the other array but that isn't necessarily the case.

In operator<< you are outputting to cout instead of the ostream object that was passed as argument.
Last edited on
Thanks for the useful tips @Peter87.
I've a question: the const version of at() will be called only to const real_array(s), so 'this' pointer is already a pointer to a const object...so why I have to cast it?
Yeah, but this is in the non-const version and in order to call the const version we need to cast this to const.

In C++17 you should be able to use std::as_const (I forgot about that).
1
2
3
4
template <typename T>
T& real_array<T>::at(size_t _n) {
    return const_cast<T&>(std::as_const(*this).at(_n));
}
Last edited on
Ops I've I completely misunderstood your hint...thanks for this explanation @Peter97.

About the initializer_list, how can I fix them? Is there something similar but with non-const access?

[Edit]
It seems no...
Last edited on
Topic archived. No new replies allowed.