реклама на сайте
подробности

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Определение размера массива на этапе компиляции, Задачка
kurtis
сообщение Sep 11 2012, 11:46
Сообщение #31


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



А чем это принципиально отличается от sizeof(a)/sizeof(a[0])?
Go to the top of the page
 
+Quote Post
dxp
сообщение Sep 11 2012, 11:51
Сообщение #32


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (kurtis @ Sep 11 2012, 18:46) *
А чем это принципиально отличается от sizeof(a)/sizeof(a[0])?

А разве из первого поста не ясно, из чего вся задача возникла? Передайте в функцию массив, чтобы внутри неё был известен размер. Размер вторым аргументом не передавать. Перечитайте первый пост.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
kurtis
сообщение Sep 11 2012, 11:57
Сообщение #33


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



Опять не понял

Код
#include <iostream>

template <typename T, int N>
int len(T (& a)[N])
{
    return N;
}

const int a[] = {1,1,1,1,2,3,4,5,6}; // 9 элементов
const int b[] = {1,1,1,5,6};  // 5 элементов

volatile int d;

int foo(const int arr[]) {
    std::cout << "len:" <<  len(arr) << "\n";
}

int main()
{
    foo(a);
    foo(b);
}

Цитата
mike@mike-work:/tmp$ LC_ALL=C g++ test.cpp
test.cpp: In function 'int foo(const int*)':
test.cpp:15:33: error: no matching function for call to 'len(const int*&)'
test.cpp:15:33: note: candidate is:
test.cpp:4:5: note: template<class T, int N> int len(T (&)[N])

Go to the top of the page
 
+Quote Post
MrYuran
сообщение Sep 11 2012, 12:37
Сообщение #34


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Закорючка лишняя.
Либо если уж разыменовывать, то &arr[0]


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
amaora
сообщение Sep 11 2012, 14:07
Сообщение #35


Местный
***

Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778



А компиляторы C++ уже способны это оптимизировать? GCC похоже может либо сделать inline либо много реализаций одного и тоже же. А так чтобы функция одна а параметры разные? только через обертку?
Go to the top of the page
 
+Quote Post
dxp
сообщение Sep 11 2012, 15:22
Сообщение #36


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (kurtis @ Sep 11 2012, 18:57) *
Опять не понял

Что тут не понятного? Вы слепили свою функцию, скормили ей массив, внутри функции массив уже не виден, а виден только указатель на него - и что, вы хотите, чтобы компилятор восстановил из указателя массив?

Заведите массив внутри вашей функции и передавайте его функции len(). Массив, а не указатель.

Именно тут и проявилась фича метода - невозможно по ошибке передать в функцию указатель - только массив. Такая ошибка гарантировано отлавливается на этапе компиляции.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
ViKo
сообщение Sep 11 2012, 17:03
Сообщение #37


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(dxp @ Sep 11 2012, 18:22) *
Именно тут и проявилась фича метода - невозможно по ошибке передать в функцию указатель - только массив.

Такая же особенность будет в простеньком
#define a_s(array) arr_sum(array, sizeof(array)/sizeof(array[0]))
Go to the top of the page
 
+Quote Post
kurtis
сообщение Sep 11 2012, 17:20
Сообщение #38


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



Цитата
Заведите массив внутри вашей функции и передавайте его функции len(). Массив, а не указатель.

Можете, пожалуйста, привести код, который решает проблему из первого сообщения?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Sep 11 2012, 18:30
Сообщение #39


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(kurtis @ Sep 11 2012, 23:20) *
Можете, пожалуйста, привести код, который решает проблему из первого сообщения?

Код
#include <iostream>

template <typename T, int N>
int len(T (& a)[N])
{
    return N;
}

const int a[] = {1,1,1,1,2,3,4,5,6}; // 9 элементов
const int b[] = {1,1,1,5,6};  // 5 элементов

int main()
{
    std::cout << "len a:" <<  len(a) << "\n";
    std::cout << "len b:" <<  len(b) << "\n";
}


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
kurtis
сообщение Sep 11 2012, 19:04
Сообщение #40


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



Чем это принципиально отличается от sizeof и как мне внутри функции узнать размер переданого массива? (ведь в этом смысл вопроса был?)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Sep 11 2012, 19:17
Сообщение #41


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(ViKo @ Sep 11 2012, 20:03) *
Такая же особенность будет в простеньком
#define a_s(array) arr_sum(array, sizeof(array)/sizeof(array[0]))

Это для числа элементов. А для просто размера - пойдем в обход, чтобы выловить передачу не-массива
Код
#define a_s(array) arr_sum(array, (sizeof(array)/sizeof(array[0])*sizeof(array[0]))

sm.gif
PS Задумался... в "чиста Си" от GCC уже столько костылей плюсовых... ужас - бери и делай закат Солнца.

Сообщение отредактировал _Pasha - Sep 11 2012, 19:20
Go to the top of the page
 
+Quote Post
dxp
сообщение Sep 12 2012, 01:36
Сообщение #42


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (ViKo @ Sep 12 2012, 00:03) *
Такая же особенность будет в простеньком
#define a_s(array) arr_sum(array, sizeof(array)/sizeof(array[0]))

В том-то и дело, что нет. sm.gif Когда вы скормите указатель в тут шаблонную функцию, вы получите ругань компилятора. А в случае макроса код будет молча скомпилирован, но размер будет получен неверный - не длина массива, а sizeof() указателя. В этом и состоит подлость, что закрадывается ошибка, которую компилятор отловить не в силах. Шаблонная функция лишена этого недостатка.

QUOTE (kurtis @ Sep 12 2012, 02:04) *
Чем это принципиально отличается от sizeof и как мне внутри функции узнать размер переданого массива? (ведь в этом смысл вопроса был?)

Вы разницу между f(A) и f(A, sizeof(A)/sizeof(A[0]) видите? Перечитайте, пожалуйста, самый первый пост внимательно, там подробно описано, чем не устраивает второй вариант и чего хочется добиться. Для конкретности, представьте, что задача состоит не в определении длины массива, а в подсчёте суммы его элементов, функция должна вернуть эту сумму.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
kurtis
сообщение Sep 12 2012, 03:41
Сообщение #43


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



Медлено начинаю понимать...

Код
#include <iostream>

template <typename T, int N>
int sum(T (& a)[N])
{
    int sum, i;
    for (i = 0, sum = 0; i < N; i++)
        sum += a[i];

    return sum;
}

const int a[] = {1,1,1,1,2,3,4,5,6}; // 9 элементов
const int b[] = {1,1,1,5,6};  // 5 элементов

int main()
{
    std::cout << sum(a) << "\n";
    std::cout << sum(b) << "\n";
}

Цитата
mike@mike-P55A-UD4:/tmp$ for i in $(nm a.out | grep sum | cut -d" " -f 3) ; do echo $i ; c++filt $i ; done
_Z3sumIKiLi5EEiRAT0__T_
int sum<int const, 5>(int const (&) [5])
_Z3sumIKiLi9EEiRAT0__T_
int sum<int const, 9>(int const (&) [9])

При выключенной оптимизации, получается 2 экземпляра функции sum(), для каждого из параметров. Конечно, это все хорошо если функции простые, и компилятор может их оптимизировать, а если нет?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Sep 12 2012, 03:51
Сообщение #44


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(kurtis @ Sep 12 2012, 01:04) *
Чем это принципиально отличается от sizeof и как мне внутри функции узнать размер переданого массива? (ведь в этом смысл вопроса был?)

Вы не совсем поняли идею. Идея именно в том, что это аналог sizeof(), но за программиста этот sizeof() автоматически подставляет компилятор.
То есть, вы вместо функции
Код
void fome_func(int arr[], size_t arr_len)
{
  for (int i = 0; i < arr_len; i++)
    foo(arr[i]);
}
пишете шаблон:
Код
template <typename T, int arr_len>
void fome_func(T (& arr)[arr_len])
{
  for (int i = 0; i < arr_len; i++)
    foo(arr[i]);
}

Здесь исключена возможность передать размер, не соответствующий массиву - это делает компилятор.
Однако при таком подходе возможно, что у вас для каждого размера массива будет сгенерирована своя функция.
Если вы этого не желаете, то можно совместить подходы:
Код
template <typename T, int arr_len>
inline void call_fome_func(T (& arr)[arr_len])
{
  fome_func(arr, arr_len);
}

Это практически полный аналог варианта с #define, но более безопасный с точки зрения контроля параметров.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
kurtis
сообщение Sep 12 2012, 03:57
Сообщение #45


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



Спасибо. Ситуация начинает проясняться.

Да, в таком контексте, действительно, интересный способ.
Go to the top of the page
 
+Quote Post

4 страниц V  < 1 2 3 4 >
Reply to this topicStart new topic
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 9th July 2025 - 10:03
Рейтинг@Mail.ru


Страница сгенерированна за 0.01492 секунд с 7
ELECTRONIX ©2004-2016