Если имелась в виду задача о написании перегрузок функции func для массивов char и указателей на char, то он никогда и не работал. Ваш код принимает и то, и то, не различая, что же он принял.
__>>уже устарел?
C>Если имелась в виду задача о написании перегрузок функции func для массивов char и указателей на char, то он никогда и не работал. Ваш код принимает и то, и то, не различая, что же он принял.
ааа, а мне почему-то показалось, что "перегрузка" звучала как "чего-нибудь типа перегрузки, чтоб токо работало".
п.с. раньше почему-то считал, что массив в с++ отождествляется с указателем на первый элемент массива. ан, оказывается (как следует из ваших примеров), — нет.
Здравствуйте, _hum_, Вы писали:
__>п.с. раньше почему-то считал, что массив в с++ отождествляется с указателем на первый элемент массива. ан, оказывается (как следует из ваших примеров), — нет.
Он не отождествляется, просто присутствует неявное преобразование массива в указатель:
4.2/1
An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue
of type “pointer to T”. The result is a pointer to the first element of the array.
Здравствуйте, XuMuK, Вы писали:
XMK>Здравствуйте, yatagarasu, Вы писали:
Y>>Всегда интересовало зачем это нужно. Вопрос тут похоже каждый месяц всплывает )
XMK>например, в массив можно положить несколько строк, разделенных \0.
В принципе, ничто не мешает интерпретировать (char *p) как (void *p), а конец данных помечать маркером, оговоренным контрактом. Например, нули разеляют строки, двойной ноль означает "всё, конец" (как двойной перенос строки в HTTP-заголовках)
Здравствуйте, alexolut, Вы писали:
A>Здравствуйте, _hum_, Вы писали:
__>>п.с. раньше почему-то считал, что массив в с++ отождествляется с указателем на первый элемент массива. ан, оказывается (как следует из ваших примеров), — нет.
A>Он не отождествляется, просто присутствует неявное преобразование массива в указатель:
A>
4.2/1
A>An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue
A>of type “pointer to T”. The result is a pointer to the first element of the array.
возможно. просто логика немного странноватая. ведь основной операцией для массива является разындексация, а для нее
The expression E1[E2] is identical (by definition) to *((E1)+(E2))
то есть, она по определению есть ни что иное, как разыменование указателя. потому, если считать что семантика выражения arr[i] включает в себя неявное приведения типа массива к указателю, то получается, что массив не имеет ни одной своей собственной операции (а работатть с ним можно только после преобразования к указателю. что довольно странно для нетривиального типа).
Здравствуйте, _hum_, Вы писали:
__>возможно. просто логика немного странноватая. ведь основной операцией для массива является разындексация, а для нее __>
__>The expression E1[E2] is identical (by definition) to *((E1)+(E2))
__>то есть, она по определению есть ни что иное, как разыменование указателя. потому, если считать что семантика выражения arr[i] включает в себя неявное приведения типа массива к указателю, то получается, что массив не имеет ни одной своей собственной операции (а работатть с ним можно только после преобразования к указателю. что довольно странно для нетривиального типа).
Выражение *((E1)+(E2)) справедливо как для массивов, так и для указателей. Из того же параграфа:
One of the expressions shall have the type “array of T” or “pointer to T” and the other shall have unscoped enumeration
or integral type.
Насчет особенных операций, например, sizeof от массива вернет размер массива (т.е. никакого неявного преобразования в указатель не будет).
Здравствуйте, alexolut, Вы писали:
A>Здравствуйте, _hum_, Вы писали:
__>>возможно. просто логика немного странноватая. ведь основной операцией для массива является разындексация, а для нее __>>
__>>The expression E1[E2] is identical (by definition) to *((E1)+(E2))
__>>то есть, она по определению есть ни что иное, как разыменование указателя. потому, если считать что семантика выражения arr[i] включает в себя неявное приведения типа массива к указателю, то получается, что массив не имеет ни одной своей собственной операции (а работатть с ним можно только после преобразования к указателю. что довольно странно для нетривиального типа).
A>Выражение *((E1)+(E2)) справедливо как для массивов, так и для указателей. Из того же параграфа: A>
A>One of the expressions shall have the type “array of T” or “pointer to T” and the other shall have unscoped enumeration
A>or integral type.
а кто говорил, что выражение несправеливо? я лишь вел к тому, что если считать оператор разыменования "звездочка" оператором, действующим только на значениях типа "указатели", то массив автоматом должен преобразовываться в этот тип в указанном выражении. ну, или второй вариант — считать, что есть два разных оператора "звездочка" — один действует на массивах, другой на указателях.
A>Насчет особенных операций, например, sizeof от массива вернет размер массива (т.е. никакого неявного преобразования в указатель не будет).
это не операция типа в исходном смысле (операция, определяющая допустимые действия над значениями, входящими в данный тип). массив и без нее останется массивом (а вот без операции разындексации массив как общепринятый тип данных исчезнет).
Здравствуйте, _hum_, Вы писали:
__>я лишь вел к тому, что если считать оператор разыменования "звездочка" оператором, действующим только на значениях типа "указатели", то массив автоматом должен преобразовываться в этот тип в указанном выражении. ну, или второй вариант — считать, что есть два разных оператора "звездочка" — один действует на массивах, другой на указателях.
Оператор один единственный, в выражении *((E1)+(E2)) происходит неявное преобразование имени массива в указатель.
A>>Насчет особенных операций, например, sizeof от массива вернет размер массива (т.е. никакого неявного преобразования в указатель не будет). __>это не операция типа в исходном смысле (операция, определяющая допустимые действия над значениями, входящими в данный тип). массив и без нее останется массивом (а вот без операции разындексации массив как общепринятый тип данных исчезнет).
Понятно, что если мы будем считать массивом только то, для чего можно выполнить разындексацию, то без разындексации это перестанет быть массивом в нашем понимании.
Но массив в первую очередь это непрерывная последовательность однотипных данных, а уж как обращаться к этим элементам, через [] или *+ дело десятое.
Здравствуйте, alexolut, Вы писали:
A>Здравствуйте, _hum_, Вы писали:
__>>я лишь вел к тому, что если считать оператор разыменования "звездочка" оператором, действующим только на значениях типа "указатели", то массив автоматом должен преобразовываться в этот тип в указанном выражении. ну, или второй вариант — считать, что есть два разных оператора "звездочка" — один действует на массивах, другой на указателях. A>Оператор один единственный, в выражении *((E1)+(E2)) происходит неявное преобразование имени массива в указатель.
то есть, я так понял, вы согласны с тем, что, де-юре, у типа "массив" нет своей собственной операции разындексации
A>>>Насчет особенных операций, например, sizeof от массива вернет размер массива (т.е. никакого неявного преобразования в указатель не будет). __>>это не операция типа в исходном смысле (операция, определяющая допустимые действия над значениями, входящими в данный тип). массив и без нее останется массивом (а вот без операции разындексации массив как общепринятый тип данных исчезнет). A>Понятно, что если мы будем считать массивом только то, для чего можно выполнить разындексацию, то без разындексации это перестанет быть массивом в нашем понимании. A>Но массив в первую очередь это непрерывная последовательность однотипных данных, а уж как обращаться к этим элементам, через [] или *+ дело десятое.
не совсем. таким свойством (непрерывная последовательность однотипных данных) обладают и структуры (если использовать директиву pack и однотипные поля). но не будете же вы говорить, что массивы — частный случай структур так что набор данных без указания операции доступа к ним не определяет тип.
Здравствуйте, _hum_, Вы писали:
__>то есть, я так понял, вы согласны с тем, что, де-юре, у типа "массив" нет своей собственной операции разындексации
Есть она или нет это не важно, т.к. результат интерпретируется так же как и для обычного указателя. Изменить это поведение для встроенного типа массива нельзя.
Единственное различие в наименовании полученного результата: для указателя это просто значение с учетом смещения, а для массива это будет называться N-ым членом массива.
A>>Но массив в первую очередь это непрерывная последовательность однотипных данных, а уж как обращаться к этим элементам, через [] или *+ дело десятое. __>не совсем. таким свойством (непрерывная последовательность однотипных данных) обладают и структуры (если использовать директиву pack и однотипные поля). но не будете же вы говорить, что массивы — частный случай структур так что набор данных без указания операции доступа к ним не определяет тип.
Структуры называть массивами, конечно, не буду. Просто не стоило моё предложение интерпретировать как полное и самодостаточное определение того, что есть массив.
Можно добавить, что массив задается типом и кол-вом членов, а для структуры требуется задавать тип и (в большинстве случаев) имя каждого члена отдельно. При этом структуры могут помимо членов-данных иметь и функции-члены, различные вложенные типы и спецификаторы доступа к членам.
Здравствуйте, alexolut, Вы писали:
A>Здравствуйте, _hum_, Вы писали:
__>>то есть, я так понял, вы согласны с тем, что, де-юре, у типа "массив" нет своей собственной операции разындексации A>Есть она или нет это не важно, т.к. результат интерпретируется так же как и для обычного указателя. Изменить это поведение для встроенного типа массива нельзя.
важно с концептуальной точки зрения — есть собственная операция, или приходится пользоваться чужой (самостоятельный это тип, или только его отголоски).
A>>>Но массив в первую очередь это непрерывная последовательность однотипных данных, а уж как обращаться к этим элементам, через [] или *+ дело десятое. __>>не совсем. таким свойством (непрерывная последовательность однотипных данных) обладают и структуры (если использовать директиву pack и однотипные поля). но не будете же вы говорить, что массивы — частный случай структур так что набор данных без указания операции доступа к ним не определяет тип. A>Структуры называть массивами, конечно, не буду. Просто не стоило моё предложение интерпретировать как полное и самодостаточное определение того, что есть массив. A>Можно добавить, что массив задается типом и кол-вом членов, а для структуры требуется задавать тип и (в большинстве случаев) имя каждого члена отдельно.
ну, так я ж и говорю, в вашем варианте массив — это частный случай структуры вида
template<typename T> struct{ T _0; T _1; T _2; <...> };
(тоже однотипные члены, тоже не требуют задания имени (ибо имена всегда стандартные _0, _1, и т. д.))
A>При этом структуры могут помимо членов-данных иметь и функции-члены, различные вложенные типы и спецификаторы доступа к членам.
Здравствуйте, _hum_, Вы писали:
__>важно с концептуальной точки зрения — есть собственная операция, или приходится пользоваться чужой (самостоятельный это тип, или только его отголоски).
Массив — тип самостоятельный. Но насчет важности я не согласен, т.к. как это реализовано в том или ином компиляторе для программиста, как потребителя, совершенно безразлично.
Он не сможет никак уловить эту разницу.
__>ну, так я ж и говорю, в вашем варианте массив — это частный случай структуры вида __>
__>template<typename T> struct{ T _0; T _1; T _2; <...> };
__>
__>(тоже однотипные члены, тоже не требуют задания имени (ибо имена всегда стандартные _0, _1, и т. д.))
Любой объект есть область памяти. А дальше уже идут частные случаи.
A>>При этом структуры могут помимо членов-данных иметь и функции-члены, различные вложенные типы и спецификаторы доступа к членам. __>ну, это в с++. а структуры есть и в обычном си.
Они много где есть. Но в данной теме речь всё же о C++ (т.к. в си нет перегрузки функций, о которых упомянул ТС).
Здравствуйте, alexolut, Вы писали:
A>Здравствуйте, _hum_, Вы писали:
__>>важно с концептуальной точки зрения — есть собственная операция, или приходится пользоваться чужой (самостоятельный это тип, или только его отголоски). A>Массив — тип самостоятельный. Но насчет важности я не согласен, т.к. как это реализовано в том или ином компиляторе для программиста, как потребителя, совершенно безразлично. A>Он не сможет никак уловить эту разницу.
__>>ну, так я ж и говорю, в вашем варианте массив — это частный случай структуры вида __>>
__>>template<typename T> struct{ T _0; T _1; T _2; <...> };
__>>
__>>(тоже однотипные члены, тоже не требуют задания имени (ибо имена всегда стандартные _0, _1, и т. д.)) A>Любой объект есть область памяти. А дальше уже идут частные случаи.
если так смотреть, то в языках программирования (для пк) нет вообще никаких типов, кроме типа целых чисел, ибо в конечном счете любой объект — это набор двоичных чисел в памяти машины
A>>>При этом структуры могут помимо членов-данных иметь и функции-члены, различные вложенные типы и спецификаторы доступа к членам. __>>ну, это в с++. а структуры есть и в обычном си. A>Они много где есть. Но в данной теме речь всё же о C++ (т.к. в си нет перегрузки функций, о которых упомянул ТС).
не, это мы уже оффтопим на тему — "насколько массив является самостоятельным типом (не сводится к указателю на буфер данных), и насколько это естественно реализовано в с++".
Здравствуйте, johny5, Вы писали:
J>К примеру, из массива можно вытащить его длину, этим мы экономим на strlen операции. С указателем размер строки утерян.
Проблема только в том, как отличить литерал от массива, заполненного вручную и не до конца.