Задача передать в функцию массив: указатель на первый член и размер
Чтобы не генерить разные тела шаблонной функции для разных статических массивов, сделал шаблонную функцию make_carray в которой вычисляется размер массива и возвращается объектик массива.
Помогите, пожалуйста, упростить и убрать вложенный вызов make_carray
#include <iostream>
using namespace std;
/* обертка для массива */template<typename T>
struct carray
{
T *parr;
size_t size;
};
/* вспомогательная функция для вычисления размера массива */template<typename T, size_t N>
carray<T> make_carray(T (&arr)[N])
{
carray<T> res = {arr, N};
return res;
}
/* сама полезная работа */void f1(const carray<int>& arr)
{
for (size_t i = 0; i < arr.size; ++i)
{
cout << arr.parr[i] << endl;
}
}
int main(int argc, char *argv[])
{
int data[] = {1, 2, 3};
f1(make_carray(data)); // вложенный вызов make_carray, от которого хочется избавитьсяreturn 0;
}
хочется чтобы работало без make_carray
int main(int argc, char *argv[])
{
int data[] = {1, 2, 3};
[b]f1(data); // избавились от вложенного вызова make_carrayreturn 0;
}
Здравствуйте, Alexander Pazdnikov, Вы писали:
AP>Помогите, пожалуйста, упростить и убрать вложенный вызов make_carray AP>хочется чтобы работало без make_carray
Здравствуйте, Alexander Pazdnikov, Вы писали:
AP>Сама функция довольно большая, хотелось предотвратить инстанцирование шаблонной функции для каждого отдельного массива.
AP>
В данном случае сгенерится одна функция, даже если второй вызов исправить на f1(d2), потому что типы d1 и d2 идентичны. Две функции сгенерятся, если, например, d2 определить так:
int d2[] = {1, 2, 3, 4};
AP>... , а функция библиотечная, т.е. используется > 20 раз сейчас, и это кол-во будет увеличиваться.
AP>Хотел уточнить — выход, так понимаю, генерить обертки функций
Ну да, в спец. перегрузке выводить размер, и потом вызывать "рабочую" функцию. И не стоит беспокоиться о количестве сгенерироанных функций-переходников — оптимизатор вполне способен выкинуть их вовсе.
Вот небольшой пример:
void __declspec(noinline) f(int* ptr, int sz)//Не встраивать, чтобы меньше кода получилось в ассемблерном листинге :)
{
for(int i = 0; i < sz; ++i)
cout << ptr[i] << '\n';
cout << '\n';
}
template <class T, int N>
void f(T (&arr)[N])
{
f(arr, N);
}
int main()
{
int a1[] = {5, 6, 7};
int a2[] = {8, 9, 10, 11};
f(a1);
f(a2);
return 0;
}
Здравствуйте, Alexander Pazdnikov, Вы писали:
AP>По-моему, как-то не правилно понял ваш совет по добалению конструктора: приходится указывать размер массива явно ? AP>Поправьте, пожалуйста.
Я думаю, jazzer имел в виду что-то такое:
template<typename T>
struct carray
{
template <int N>
carray(T (&arr)[N]) : parr(arr), size(N) {}
T *parr;
size_t size;
};
/* сама полезная работа */void f1(const carray<int>& arr)
{
for (size_t i = 0; i < arr.size; ++i)
{
cout << arr.parr[i] << endl;
}
}
int main(int argc, char *argv[])
{
int data[] = {1, 2, 3};
f1(data);
return 0;
}
Любите книгу — источник знаний (с) М.Горький
Re[4]: Помогите с выведением и преобразованием типа
Здравствуйте, Alexander Pazdnikov, Вы писали:
AP>Число академический интерес, как можно шаблонизировать функцию f1 для вывода типа T элементов массива
В данном случае никак — преобразование T[N] -> carray<T> не рассматривается. Нужно либо явно указыватьпараметр шаблона при вызове, либо использовать вариант без carray.