Использовать один и тот-же шаблон для трехмерного и одномерного массива
У меня есть шаблон, который принимает трехмерный массив для нахождения максимума. Суть задачи состоит в том, что этот шаблон должен находить максимум и в одномерном массиве. У нас добавляется переменная char question if question = '1' = трехмерный, если 2, то одномерный.
Вот мой шаблон -
template<typename T2>
T2 maxShablon2(T2 ***arr, const int n) {
int max = arr[0][0][0];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
for (int k = 0; k < n; ++k) {
if (arr[i][j][k] > max) {
max = arr[i][j][k];
}
}
}
}
cout << " Our max: " << max;
}
Ответы (3 шт):
T2 ***arr это плохой массив. Это вообще неизвестно что, толи 1 значение, толи указатель на массив указателей на элементы....
В C++ должно быть примерно так:
#include <iostream>
#include <ctime>
#include <vector>
#include <algorithm>
#include <optional>
#include <numeric>
#include <random>
using namespace std;
template<typename Cont, typename T>
optional<T> maxShablon2(Cont const& data)
{
if constexpr (is_same<T, typename Cont::value_type >())
{
if (auto it = std::max_element(data.begin(), data.end()); it != data.end())
return *it;
return {};
}
else
{
auto acc_func = [](optional<T> const& a, typename Cont::value_type const& b)->optional<T>
{
auto b_res = maxShablon2<typename Cont::value_type, T>(b);
if (!b_res) return a;
if (!a) return b_res;
if (*a > b_res)return a;
return b_res;
};
return std::accumulate(data.begin(), data.end(), optional<T>{}, acc_func);
}
}
int main()
{
vector<vector<vector<int>>> v;
mt19937_64 rg((uint64_t)time(nullptr));
v.resize(3);
for (auto& v_x : v)
{
v_x.resize(3);
for (auto& v_xy : v_x)
{
v_xy.resize(3);
for (auto& e : v_xy)
e = uniform_int_distribution(1, 1000)(rg);
}
}
cout << maxShablon2<decltype(v), int>(v).value_or(-123456);
printf("Hello World");
return 0;
}
Если таки работать надо с массивами, то как вариант:
template<typename Arr>
auto maxValue(const Arr& a) -> typename remove_all_extents<Arr>::type
{
static_assert(rank<Arr>::value,"[] type only :)");
using T = typename remove_all_extents<Arr>::type;
T res = numeric_limits<T>::min();
if constexpr(rank<Arr>::value == 1)
{
for(int i = 0; i < extent<Arr>::value; ++i)
if (res < a[i]) res = a[i];
}
else
{
for(int i = 0; i < extent<Arr>::value; ++i)
{
T val = maxValue(a[i]);
if (res < val) res = val;
}
}
return res;
}
int main(int argc, char * argv[])
{
int a3[3][2][2] = {
{{1,2},{3,4}},
{{5,6},{7,8}},
{{0,2},{2,4}},
};
int a1[5] = { 1, 5, 2, 9, 7 };
cout << maxValue(a3) << endl;
cout << maxValue(a1) << endl;
}
Вот рабочая программа. Размерность массива роли не играет.
И никакой q вообще не нужен.
Массивы располагаются в памяти последовательно, поэтому ответ Harry можно переделать так:
template<typename Arr>
auto maxValue(const Arr& a) -> typename
remove_all_extents<Arr>::type {
using T = typename remove_all_extents<Arr>::type;
const T* v = reinterpret_cast<const T*>(&a[0]);
T res = numeric_limits<T>::min();
for (int i = 0; i < sizeof(a) / sizeof(T); ++i)
if (v[i] > res) res = v[i];
return res;
}