It's been quite some time since I've lasted tackled a programming assignment, so forgive me for what might be dumb questions. So I'm trying to get a grasp on this project I have where I'm implementing a templated array with some static assertions and without using STD types. The arrays in my test cases are of fixed lengths.
Basically, my question is, wherever the comments do not say "TODO", those class methods are pretty much set and I don't have to write any code for them to work?
#ifndef ARRAY_HPP
#define ARRAY_HPP
#include <ostream>
template <typename T, std::size_t Length>
class Array
{
public:
// Static assert that prohibits arrays of length 0
static_assert(Length != 0, "Array cannot be of length 0";
Array();
~Array();
Array(const Array& other);
Array& operator=(const Array& other);
// Returns the size of the array.
std::size_t size() const;
// Returns the first or last element of the array. Ideally, there would be non-const overloads for these too.
const T& front() const;
const T& back() const;
/**
* Returns the element of the array that is at the given index.
* Throws std::out_of_range if index is out of range.
*/
T& at(std::size_t index);
const T& at(std::size_t index) const;
/**
* Equality checking, i.e. checking if two arrays contain the exact
* same elements.
*/
booloperator==(const Array& other) const;
booloperator!=(const Array& other) const;
private:
// TODO: Your member variables and helper methods go here.
};
/*
* Returns the element of the array that is at the given index.
* Causes compilation to fail (with a static assertion) if index is out
* of range.
*/
template <std::size_t Index, typename T, std::size_t Length>
T& get(Array<T, Length>& array);
template <std::size_t Index, typename T, std::size_t Length>
const T& get(const Array<T, Length>& array);
// Prints each element of the array.
template <typename T, std::size_t Length>
std::ostream& operator<<(std::ostream& os, const Array<T, Length>& array);
#endif // ARRAY_HPP
Basically, my question is, wherever the comments do not say "TODO", those class methods are pretty much set and I don't have to write any code for them to work?
A function needs a body. So when there is a function without a body you probably need to implement them which seems pretty much all of them.
It is not too hard. Most of them require just a single line of code and maybe a [static] assert.
So far I've gotten up to returning the size of the array, which was pretty straightforward. But now I'm stuck on trying to return the first and last elements of the array. I understand how to return them if we were explicitly given the elements of the array, but since my test cases define them in different arrays, how would I do this in a single line of code?
is the basis of front() and back() since at() is just grabbing the value at a specific index?
Yes. front() returns the first element, and back() returns the last. Use at() to index into your implementation to find those elements, and return them.
template <typename T, std::size_t Length>
class Array
{
public:
...
/**
* Returns the element of the array that is at the given index.
* Throws std::out_of_range if index is out of range.
*/
T& at(std::size_t index)
{
if(index < Length)
return Value[index];
elsethrow std::out_of_range{"Out of Range error"};
}
...
private:
// TODO: Your member variables and helper methods go here.
T Value[Length];
};
at is notably slower than [].
you can use at if you are unsure that your index is in range and to throw the error, that is its purpose, but use [] when you know it is safe to do so.
I've tried implementing the get() function, but my static assertion throws for this test case when it should not. I also get this error when I try to return Length "binary '[': 'Array<std::string,3>' does not define this operator or a conversion to a type acceptable to the predefined operator".
/**
* Returns the element of the array that is at the given index.
* Causes compilation to fail (with a static assertion) if index is out
* of range.
*/
template <std::size_t Index, typename T, std::size_t Length>
T& get(Array<T, Length>& array)
{
// Static assertion that causes compilation to fail if the given index is out of range.
static_assert(Index > Length, 'Index is out of range');
// Retrieve the element
if (index < Length)
return array[Length]; // this is where my error points to
}
Also, I'm having trouble trying to print out the elements of the array. I'm thinking of using a for loop, but unsure if I'm right. Here is my implementation. I also receive the same error above.
1 2 3 4 5 6 7 8 9
template <typename T, std::size_t Length>
std::ostream& operator<<(std::ostream& os, const Array<T, Length>& array)
{
// doesn't work
for (int i = 0; i < Length; i++) {
os << array[i]; // this is where my error points to
return os;
}
}
I'm not exactly sure what you're alluding to? Arrays start will 0 as their subscript and depending on their size, the subscript is the last index of the array no? I'm assuming when you say subscript, you mean indexes.
/**
* Returns the element of the array that is at the given index.
* Causes compilation to fail (with a static assertion) if index is out
* of range.
*/
template <std::size_t Index, typename T, std::size_t Length>
T& get(Array<T, Length>& array)
{
// Static assertion that causes compilation to fail if the given index is out of range.
static_assert(Index < Length, "Index is out of range"); // The assumption is < // A string has ""
// Retrieve the element
if (index < Length) // static_assert prevent this
return array.get(index); // Your array currentlly does not support []
}
Similar:
1 2 3 4 5 6 7 8 9
template <typename T, std::size_t Length>
std::ostream& operator<<(std::ostream& os, const Array<T, Length>& array)
{
// doesn't work
for (int i = 0; i < Length; i++) {
os << ' ' << array.get(i); // No [] // Consider using whitespace to separate the values
return os;
}
}