#include <iostream>
class RowBase
{
public:
virtualvoid scan() = 0;
};
template< int N > //Non-type Template Arguments
class Row : public RowBase
{
private:
int samples[ N ]; //array of samples
public:
void scan()
{
for (int i=0; i<N; i++)
{
samples[i] = i;
std::cout << samples[i];
}
}
};
class Matrix
{
private:
RowBase*const *const ptrsRows; //array of row pointers
public:
template<int N>
Matrix(Row<N>*const *const pr): ptrsRows(pr) {}
};
//********** ROWS ***********
constint N=3;
Row< N > row0;
Row< N > row1;
//********** MATRIX ***********
Row< N >* const ptrsRows[] = { &row0, &row1 }; //array of row pointers
Matrix matrix(ptrsRows);
int main()
{
row1.scan();
}
Output:
template_ptrArray.cpp: In instantiation of Matrix::Matrix(Row<N>* const*) [with int N = 3]':
template_ptrArray.cpp:41:23: required from here
template_ptrArray.cpp:31:46: error: invalid conversion from 'Row<3>* const*' to 'RowBase* const*' [-fpermissive]
Matrix(Row<N>*const *const pr): ptrsRows(pr) {}
Similar error messages posted online have incongruent number dereference operators e.g.
invalid conversion from 'int*' to 'int'
But in my error message, the number of dereference operators match.
DO not ever manually cast pointers to arrays. Ever.
Imagine what happens if base class have size of 2 and derived 3
1 2 3 4 5 6 7 8 9 10 11
//Memory layouts of Someclass t[] = {x, y, z} and pointer returned by t[1]
//for base
XXYYZZ
↑
//For derived
XXXYYYZZZ
↑
//If we cast derived* to base* and make t[1]:
XXXYYYZZZ
↑
You see, compiler will return pointer to not the beginning of second objec, but inside first.
To solve the need to store in single array objects of different types, you can make proxy which would contain [smart]pointer to actual objects. Or use std::reference_wrapper. Or store array of pointers to base type.
I thought an array can always be implicitly converted to the pointer of the proper type.
No, arrays cannot be converted to the pointer of the base type. It is dangerous. If anyone will suggest reinterpret_cast to solve that, just smack them in the face. I posted why earlier. You can initialize RowBase array with derived pointers: RowBase* pr[] = {&row0, &row1};
Why do you need to use pointers, C-arrays and other hard-to-handle stuff?
Hi MiiNiPaa,
The code will be Arduino firmware for a keyboard library.
Arduino does not have access to Vector, Boost libraries or C++11.
The scan() function scans the keyboard matrix.
I already have the firmware running on a keyboard.
Now I am porting the keyboard firmware to a Keyboard library to make writing custom keyboard firmware easy.
But moving the Row class into a library is proving to be difficult.
Just take vector implementation from some compiler library, cut parts which you do not need and you now have something vector-like. Or just write it yourself.