Как возвратить ссылку на массив??
От: Fynjisx  
Дата: 07.07.08 08:19
Оценка:
Привет Всем!
Пишу на С++. Написал функцию, которая должна возвращать ссылку на массив...Как правильно написать сигнатуру такой функции???
Заранее благодарен.., спасибо..
Заранее благодарю.
С уважением Fynjisx
Re: Как возвратить ссылку на массив??
От: jazzer Россия Skype: enerjazzer
Дата: 07.07.08 08:29
Оценка: 1 (1) +1
Здравствуйте, Fynjisx, Вы писали:

F>Привет Всем!

F>Пишу на С++. Написал функцию, которая должна возвращать ссылку на массив...Как правильно написать сигнатуру такой функции???
F>Заранее благодарен.., спасибо..


int (&f(/*тут параметры функции*/)) [5];


вернет ссылку на массив int[5]

или (что читабельнее):
typedef int XXX[5];
XXX& f(double x);
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Как возвратить ссылку на массив??
От: Кодт Россия  
Дата: 07.07.08 16:11
Оценка: 1 (1) +1
Здравствуйте, Fynjisx, Вы писали:

F>Пишу на С++. Написал функцию, которая должна возвращать ссылку на массив...Как правильно написать сигнатуру такой функции???


А зачем?

Если это какой-то высокий пилотаж с автоматическим выводом типов, то можно найти решение (jazzer уже привёл).
В противном случае — достаточно возвращать указатель на элемент (потеряв размер), либо ссылку на контейнер (std::vector, boost::array).
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[2]: Как возвратить ссылку на массив??
От: Sergey Chadov Россия  
Дата: 07.07.08 16:19
Оценка:
Здравствуйте, jazzer, Вы писали:

J>
J>int (&f(/*тут параметры функции*/)) [5];
J>


J>вернет ссылку на массив int[5]


J>или (что читабельнее):

J>
J>typedef int XXX[5];
J>XXX& f(double x);
J>


Но ради морального здоровья того, кому этот код придется сопровождать, так делать не стоит.
--
Sergey Chadov

... << RSDN@Home 1.2.0 alpha rev. 685>>
Re[3]: Как возвратить ссылку на массив??
От: jazzer Россия Skype: enerjazzer
Дата: 07.07.08 16:51
Оценка: +1
Здравствуйте, Sergey Chadov, Вы писали:

SC>Здравствуйте, jazzer, Вы писали:


J>>
J>>int (&f(/*тут параметры функции*/)) [5];
J>>


J>>вернет ссылку на массив int[5]


J>>или (что читабельнее):

J>>
J>>typedef int XXX[5];
J>>XXX& f(double x);
J>>


SC>Но ради морального здоровья того, кому этот код придется сопровождать, так делать не стоит.


ну, проблем в варианте с тайпдефом я не вижу — все просто и понятно и без всяких шаблонов.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Как возвратить ссылку на массив??
От: k732  
Дата: 08.07.08 17:43
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Fynjisx, Вы писали:


F>>Пишу на С++. Написал функцию, которая должна возвращать ссылку на массив...Как правильно написать сигнатуру такой функции???


К>А зачем?


К>Если это какой-то высокий пилотаж с автоматическим выводом типов, то можно найти решение (jazzer уже привёл).

К>В противном случае — достаточно возвращать указатель на элемент (потеряв размер), либо ссылку на контейнер (std::vector, boost::array).

Не согласен. Есть код работающий с массивами(в чистом С-смысле).
Есть классы-обертки над данными массивами. У них конечно есть stl-контейнеры, но вот все-таки нужно запихнуть C-массив, причем четко ограниченного размера. Тоесть если меньше или больше — то расстрел.

Можно конечно написать конструктор, который проверяет размеры, но зачем делать чужую работу, если компилятор и сам это сделает.

Пример:
class S{
    private :
        std::vector<unsigned char> m_vector;

    public :
        S (const std::vector<unsigned char>& vector) : m_vector (vector) {}
        ~S () {}
}


Без лишних телодвижений напишите конструктор неявного преобразования из C-массива в S-класс без дополнительных проверок.
Re[3]: Как возвратить ссылку на массив??
От: Кодт Россия  
Дата: 08.07.08 18:38
Оценка:
Здравствуйте, k732, Вы писали:

К>>Если это какой-то высокий пилотаж с автоматическим выводом типов, то можно найти решение (jazzer уже привёл).

К>>В противном случае — достаточно возвращать указатель на элемент (потеряв размер), либо ссылку на контейнер (std::vector, boost::array).

K>Не согласен. Есть код работающий с массивами(в чистом С-смысле).

<...>
K>Без лишних телодвижений напишите конструктор неявного преобразования из C-массива в S-класс без дополнительных проверок.

А это и есть тот самый пилотаж. Так что я не согласен с твоим "не согласен"

class S
{
    .....
    template<class E, size_t N> S(E const(& arr) [N])
        : m_vector(arr, arr+N)
    {}
}



И всё-таки, голый массив — это ущербный тип.
— инициализировать его можно либо неявно (будучи членом структуры, у которой есть определённый пользователем конструктор без параметров и/или копирования), либо агрегатно
— присваивать — только неявно
— создавать на куче — только неявно
Хуже, чем ссылочный тип, право слово. Ссылочный можно хотя бы инициализировать по-человечески.

Поэтому использовать ссылки на массивы — я по возможности избегаю. Только для передачи массивов в функции. Но для возвращения их из функций —
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[4]: Как возвратить ссылку на массив??
От: Кодт Россия  
Дата: 08.07.08 18:38
Оценка:
Здравствуйте, jazzer, Вы писали:

J>ну, проблем в варианте с тайпдефом я не вижу — все просто и понятно и без всяких шаблонов.


Просто, до тех пор, пока не попробуешь
XXX x;
XXX y = x; // ошибка: должно инициализировать агрегатом
XXX *z = new XXX; // ошибка - смешаны типы массива и указателя
x = y; // ошибка: нельзя присваивать массив

А был бы boost::array<double,5> — все вопросы снялись бы.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[4]: Как возвратить ссылку на массив??
От: k732  
Дата: 08.07.08 18:52
Оценка:
К>А это и есть тот самый пилотаж. Так что я не согласен с твоим "не согласен"

К>
К>class S
К>{
К>    .....
К>    template<class E, size_t N> S(E const(& arr) [N])
К>        : m_vector(arr, arr+N)
К>    {}
К>}
К>



К>И всё-таки, голый массив — это ущербный тип.

Не спорю, но спри разборе (нпример пакетов) все что нам дают(зачастую) — POD типы.

К>- инициализировать его можно либо неявно (будучи членом структуры, у которой есть определённый пользователем конструктор без параметров и/или копирования), либо агрегатно

К>- присваивать — только неявно
К>- создавать на куче — только неявно

не совсем понял про выше сказанное

К>Хуже, чем ссылочный тип, право слово. Ссылочный можно хотя бы инициализировать по-человечески.

К>Поэтому использовать ссылки на массивы — я по возможности избегаю. Только для передачи массивов в функции. Но для возвращения их из функций —

имеется ввиду

К>Поэтому использовать ссылки на массивы - я по возможности избегаю. Только для передачи массивов в функции. Но НЕ для возвращения их из функций -  :xz:


?
Re[5]: Как возвратить ссылку на массив??
От: jazzer Россия Skype: enerjazzer
Дата: 08.07.08 19:01
Оценка: 1 (1)
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, jazzer, Вы писали:


J>>ну, проблем в варианте с тайпдефом я не вижу — все просто и понятно и без всяких шаблонов.


К>Просто, до тех пор, пока не попробуешь

К>
К>XXX x;
К>XXX y = x; // ошибка: должно инициализировать агрегатом
К>XXX *z = new XXX; // ошибка - смешаны типы массива и указателя
К>x = y; // ошибка: нельзя присваивать массив
К>


А вот все эти ошибки — это, имхо, баги в языке.
Ибо я не вижу ни одного разумного аргумента, по которому массивы должны трактоваться не так, как остальные агрегаты (struct, например).
Если знаешь — поделись

К>А был бы boost::array<double,5> — все вопросы снялись бы.


А boost::array — это просто средство объехать эти баги.
Сделали бы нормальные массивы — boost::array и не появился бы.

Согласен?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: Как возвратить ссылку на массив??
От: uzhas Ниоткуда  
Дата: 08.07.08 19:05
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, jazzer, Вы писали:


J>>ну, проблем в варианте с тайпдефом я не вижу — все просто и понятно и без всяких шаблонов.


К>Просто, до тех пор, пока не попробуешь

К>
К>XXX x;
К>XXX y = x; // ошибка: должно инициализировать агрегатом
К>XXX *z = new XXX; // ошибка - смешаны типы массива и указателя
К>x = y; // ошибка: нельзя присваивать массив
К>

хотелось бы добавить
  delete new XXX;
Re[6]: Как возвратить ссылку на массив??
От: Кодт Россия  
Дата: 08.07.08 19:37
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Сделали бы нормальные массивы — boost::array и не появился бы.

J>Согласен?

Но, как говорится, не по хорошу мил, а по милу хорош.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[5]: Как возвратить ссылку на массив??
От: Кодт Россия  
Дата: 08.07.08 19:37
Оценка:
Здравствуйте, k732, Вы писали:

K>Не спорю, но спри разборе (нпример пакетов) все что нам дают(зачастую) — POD типы.


Ну и заверни массив в структуру. Тут-то счастье и наступит.

К>>- инициализировать его можно либо неявно (будучи членом структуры, у которой есть определённый пользователем конструктор без параметров и/или копирования), либо агрегатно

К>>- присваивать — только неявно
К>>- создавать на куче — только неявно

K>не совсем понял про выше сказанное


jazzer'у уже ответил.
struct A { ..... int arr[10]; ..... }; // не обязательно POD, но к POD всё так же применимо

// вот так можно
A x;
A y = A(); // default ctor (+ подразумевается copy ctor)
A z = x; // copy ctor
x = y;
delete new A(); // default ctor


К>>Хуже, чем ссылочный тип, право слово. Ссылочный можно хотя бы инициализировать по-человечески.

К>>Поэтому использовать ссылки на массивы — я по возможности избегаю. Только для передачи массивов в функции. Но для возвращения их из функций —

K>имеется ввиду

, что возвращать их из функций — это для меня " "
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re: Как возвратить ссылку на массив??
От: Константин Черногория  
Дата: 10.07.08 00:29
Оценка:
Добрый вечер, Fynjisx, Вы писали:

F>Привет Всем!

F>Пишу на С++. Написал функцию, которая должна возвращать ссылку на массив...Как правильно написать сигнатуру такой функции?

Если массив константного размера, и ты программируешь в MSDEV — я бы порекомендовал следующую сигнатуру:
HRESULT MyFunc(int arr[5]);

Внутри функции — просто пишешь шо-то вроде arr[4]=0;
Снаружи — пишешь чо-нить вроде
int buff[5];
hr = MyFunc(buff);
if(FAILED(hr)){...}

Если же массив переменного размера, то IMO без ATL/STL-ных контейнеров не обойтись..
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.