I'm reinventing std::array
with minimal functions:
#include <iostream>
#include <cstddef>
template <typename T, size_t N>
class MyArray {
public:
class Iterator {
public:
Iterator(): ptr(nullptr) {}
T &operator*() { return *ptr; }
T *operator->() { return ptr; }
// Iterator + Int
Iterator operator+(int n) { return Iterator(ptr + n); }
private:
Iterator(T *ptr): ptr(ptr) {}
T *ptr;
friend class MyArray;
};
T &operator[](int n) { return arr[n]; }
Iterator begin() { return Iterator(arr); }
Iterator end() { return Iterator(arr + N); }
private:
T arr[N];
};
// Int + Iterator
template<typename T, size_t N>
typename MyArray<T, N>::Iterator operator+(int n, typename MyArray<T, N>::Iterator it) {
return it + n;
}
int main(void) {
MyArray<long, 10> arr;
arr[0] = 0;
arr[1] = 1;
auto it = arr.begin();
std::cout << *it << std::endl; // prints 0
std::cout << *(it + 1) << std::endl; // prints 1
std::cout << *(1 + it) << std::endl; // compile error!
}
As shown above, it supports indexing and a forward iterator. However, operator overloading for int
+ iterator raises a compile error. GCC 12.1.0 says:
test.cpp: In function ‘int main()’:
test.cpp:44:22: error: no match for ‘operator+’ (operand types are ‘int’ and ‘MyArray<long int, 10>::Iterator’)
44 | std::cout << *(1 + it) << std::endl; // compile error!
| ~ ^ ~~
| | |
| int MyArray<long int, 10>::Iterator
test.cpp:32:34: note: candidate: ‘template<class T, long unsigned int N> typename MyArray<T, N>::Iterator operator+(int, typename MyArray<T, N>::Iterator)’
32 | typename MyArray<T, N>::Iterator operator+(int n, typename MyArray<T, N>::Iterator it) {
| ^~~~~~~~
test.cpp:32:34: note: template argument deduction/substitution failed:
test.cpp:44:24: note: couldn’t deduce template parameter ‘T’
44 | std::cout << *(1 + it) << std::endl; // compile error!
I don't know why the compiler can't deduce template parameter T
. In my point of view it must be trivially long
.