"small_cat" <3877@users.rsdn.ru> wrote in message news:1902996@news.rsdn.ru... > Доброго времени суток. > > Пытаюсь сделать следующее: > > >
> struct TStruct
> {
> //
> };
>
> const int N = 1000000;
> typedef TStruct TStructArray[N];
>
> //и дальше
> TStructArray* arr = new TStructArray;
>
> > Ошибка C2440, (не может TStruct* привести к TStructArray(*)) > > Что я делаю не так? > Спасибо.
Правильно так:
TStruct* arr = new TStructArray;
Выражение new TStructArray эквивалентно выражению new TStruct[N]. Т.е. вданном случе вместо operator newвызывается operator new[]. Убедиться в этом можно так:
void* operator new[](std::size_t n)
{
std::cout << "new[]" << std::endl;
return 0;
}
int main()
{
struct TStruct{};
const int N = 1000000;
typedef TStruct TStructArray[N];
TStruct* arr = new TStructArray; //На экран выводится "new[]"
}
Posted via RSDN NNTP Server 2.0
--
Не можешь достичь желаемого — пожелай достигнутого.
> > Эх, велик и приплюснут сишный язык. > > Ну на кой оно так сделано? >
На мой взгляд достаточно логично и удобно: если взять любое объявление переменной, функции или массива и добавить к нему typedef, то получится объявление типа.
Posted via RSDN NNTP Server 2.0
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>На мой взгляд достаточно логично и удобно: если взять любое объявление переменной, функции или массива и добавить к нему typedef, то получится объявление типа.
А с какой стати массив объявляется как char G[12], а не как char[12] G?
" Кодёнок " <16798@users.rsdn.ru> wrote in message news:1903220@news.rsdn.ru... > Здравствуйте, rg45, Вы писали: > > R>На мой взгляд достаточно логично и удобно: если взять любое объявление переменной, функции или массива и добавить к нему typedef, то получится объявление типа. > > А с какой стати массив объявляется как char G[12], а не как char[12] G?
Ну тут я затрудняюсь ответить, таков уж синтаксис. Если рассуждать в таком ключе, то можно спросить: "почему объявление функции выглядит как char g(int), а не как char(int) g ?". Кроме того конструкции подобные char[12] вполне законны в тех местах, где идентификатор принято опускать, например:
template<typename T> class Foo;
template<> class Foo<char[12]> {/*...*/};
Posted via RSDN NNTP Server 2.0
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
>> А с какой стати массив объявляется как char G[12], а не как char[12] G?
R>Ну тут я затрудняюсь ответить, таков уж синтаксис. Если рассуждать в таком ключе, то можно спросить: "почему объявление функции выглядит как char
Вот сам синтаксис объявления переменной я считаю нелогичным и неудобным. Поэтому typedef, который его копирует, язык не поворачивается назвать логичным и удобным
" Кодёнок " <16798@users.rsdn.ru> wrote in message news:1903294@news.rsdn.ru... > Здравствуйте, rg45, Вы писали: > >>> А с какой стати массив объявляется как char G[12], а не как char[12] G? > > R>Ну тут я затрудняюсь ответить, таков уж синтаксис. Если рассуждать в таком ключе, то можно спросить: "почему объявление функции выглядит как char > > Вот сам синтаксис объявления переменной я считаю нелогичным и неудобным. Поэтому typedef, который его копирует, язык не поворачивается назвать логичным и удобным
Наверное, рациональное зерно в этом есть. Правила разбора выражений могли бы здорово упроститься, если бы, например, ссылка на массив объявлялась не так: char (&ref)[12], а так: char[12]& ref. А при разборе таких выражений как функция, возвращающая указатель на функцию вообще окосеть можно:
//foo - функция, принимающая агрумент типа const char*
//и возвращающая указатель на функцию с сигнатурой void f(int)void (*foo(const char*) ) (int);
Конечно, при помощи промежуточных typedef можно сделать это выражение гораздо более читабельным, но не всегда это возможно, например при специализации шаблонов, промежуточные typedef сделать не получается.
Posted via RSDN NNTP Server 2.0
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, Кодёнок, Вы писали:
Кё>А с какой стати массив объявляется как char G[12], а не как char[12] G?
Наследие B and BCPL. И массивы тесно связаны с поинтерами, в раннем С и поинтеры объявлялись не так, как сейчас:
Embryonic C
NB existed so briefly that no full description of it was written. It supplied the types int and char, arrays of them, and pointers to them, declared in a style typified by
int i, j;
char c, d;
int iarray[10];
int ipointer[];
char carray[10];
char cpointer[];
The semantics of arrays remained exactly as in B and BCPL: the declarations of iarray and carray create cells dynamically initialized with a value pointing to the first of a sequence of 10 integers and characters respectively. The declarations for ipointer and cpointer omit the size, to assert that no storage should be allocated automatically.
Хотя потом для поинтеров "спецсимвол" перенесли до имени. А для массивов — нет, видимо следуя принципу — синтаксис объявления напоминает использование.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, Константин Л., Вы писали:
КЛ>И зря, c#'ный type[] var мне больше нравится.
Да пожалуй все проблемы С и С++ — следствия обратной совместимости. А когда их предки развивались, были совсем другие проблемы.
и так:
char i,*p,a[5];
писали не от хорошей жизни, а т.к памяти было мало. Это сейчас сорец в 20Кб смешным выглядит, а когда-то такой гигантский размер для ядра ОС был роскошью.
Это сейчас сидят толпы академиков пишут научные труды и сочиняет самые правильные языки. А тогда несколько хакеров-самоучек накатали на коленке ОС да и компилятор заодно. И как люди этим пользуются, когда есть Оберон
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, Draqon, Вы писали:
D>Советую глянуть в сторону std::vector<TStruct>.
Или boost::array<TStruct,N>.
Кстати, boost::array<T,N> это STL-совместимая обёртка над T data[N]. То, что ты хотел написать, но обломался об синтаксис С++.
А зачем тебе динамически размещаемый массив фиксированного размера?
Здравствуйте, small_cat, Вы писали:
К>>А зачем тебе динамически размещаемый массив фиксированного размера?
_>Массив большой, не хочу на стеке размещать. Опять же, хотелось единообразия для последующей упаковки его в структуру.
Если не заморачиваться с чистотой типов, то достаточно T* arr = new T[N]; (здесь теряется compile-time информация о размере массива).
Опять же, vector<T> arr(N); (информация о размере доступна в run-time, через arr.size()).
А если хочется compile-time, то boost::array<T,N> или его аналоги. Но там будет некрасивый доступ к элементам:
Здравствуйте, rg45, Вы писали:
R>Выражение new TStructArray эквивалентно выражению new TStruct[N]. Т.е. вданном случе вместо operator newвызывается operator new[].
Очень инетересно, всегда был уверен, что вызываемый operator new зависит от синтаксиса выражения new, а не от типа. Если кому интересно, вот подтверждение из стандарта:
(5.3.4/5):
When the allocated object is an array (that is, the direct-new-declarator syntax is used or the new-type-id or type-id denotes an array type) ...
(5.3.4/8):
...
If the allocated type is a non-array type, the allocation function’s name is operator new and the deallocation function’s name is operator delete. If the allocated type is an array type, the allocation function’s name is operator new[] and the deallocation function’s name is operator delete[].