У вас есть некоторые недоразумения здесь. Самое важное: void**
НЕ является обобщенным c указателем. Единственный общий указатель c - void*
. Таким образом, ваш тип void**
может содержать адрес универсального c void*
. Это вам нужно понять.
Итак, независимо от того, сколько измерений будет иметь ваш массив, вы можете присвоить его void*
. И позже вы несете ответственность за то, чтобы привести его к нужному вам типу. См .:
// Create a 5 dimensional array
char***** dimension5 = static_cast<char*****>( malloc(200));
// Assign it to a generic pointer
void* generic = dimension5;
// Get the address of the generic pointer
void** addressOfGeneric = &generic;
// Now dereference the address of the generic pointer to get back the generic pointer
// and cast it to our original type
char***** dimension5Later = static_cast<char*****>(*addressOfGeneric);
// Do something with the array
dimension5Later[0][0][0][0][0] = 'H';
Но, конечно, мы бы никогда этого не сделали. В C ++ мы никогда не должны использовать необработанные указатели для собственной памяти. Мы должны стараться вообще избегать необработанных указателей и работать с умными указателями. Мы не должны использовать malloc
, и мы даже не должны использовать new
и вместо этого некоторую make_unique
-функцию.
Интересно, нужно ли вам это вообще. Потому что вы должны использовать std::vector
.
Пожалуйста, смотрите следующее:
// The dimension of our 2d vector
constexpr size_t NumberOfRows = 2U;
constexpr size_t NumberOfColumns = 5U;
bool somelogictellsfloat{ true };
// Depending on what to create
if (somelogictellsfloat) {
// Create and initialize a 2d vector for floats
std::vector<std::vector<float>> mArrayFloat(NumberOfRows, std::vector<float>(NumberOfColumns, 0.0));
}
else {
// Create and initialize a 2d vector for doubles
std::vector<std::vector<double>> mArrayDouble(NumberOfRows, std::vector<double>(NumberOfColumns, 0.0));
}
Но то, что вы действительно хотите, это использовать абстрактный шаблон фабрики. Если вы не знаете, пожалуйста, прочитайте об этом.
Кстати. Я сделал для вашего оригинального кода минимально воспроизводимый пример. Это вы всегда должны делать в вопросах о SO.
Я исправил некоторые ошибки и сделал его компилируемым. Но, пожалуйста, не используйте
#include <cstring>
#include < cstdlib >
#include <vector>
struct MyClass {
void** m2DArray; // Address of a generic pointer
void* md;
float** mArrayFloat;
double** mArrayDouble;
using int32 = int;
template <typename SampleType>
void initiliaze2DArray(SampleType** m2DArrayTyped)
{
m2DArrayTyped = new SampleType * [2]; //2 rows
int32 sizeOfOneCol = 5 * sizeof(SampleType); // 5 cols
for (int32 row = 0; row < 2; row++)
{
m2DArrayTyped[row] = new SampleType[5];
memset(m2DArrayTyped[row], 0, sizeOfOneCol);
}
md = m2DArrayTyped; // md is now a generic pointer
m2DArray = &md; // and m2DArray is the address of that generic pointer
}
// Test function
void test(bool doFloatAndNotDouble) {
if (doFloatAndNotDouble) {
initiliaze2DArray(mArrayFloat);
}
else {
initiliaze2DArray(mArrayDouble);
}
}
};
// Driver code
int main() {
MyClass mc{};
mc.test(true);
mc.test(false);
return 0;
}