В C++, как и в C, параметр, объявленный как тип массива, настраивается (во время компиляции) так, чтобы он имел тип указателя, в частности, указатель на тип элемента массива.
Это происходит независимо от того, указан ли тип массива напрямую или через typedef (помните, что typedef не создает новый тип, а только псевдоним для существующего типа).
Итак, это:
typedef char ar[];
typedef char* pr;
void f2(ar x, pr y)
{
// ...
}
действительно означает:
void f2(char* x, char* y)
{
// ...
}
Другое правило, также разделяемое C и C++, заключается в том, что выражение типа массива в большинстве, но не во всех контекстах неявно преобразуется в указатель на первый элемент массива. объект массива. Это означает, что если вы определяете объект массива:
char arr[10];
вы можете использовать имя этого объекта в качестве аргумента функции, которая принимает параметр char*
(который теряет информацию о границах).
В C случаи, когда это неявное преобразование не выполняется:
- Когда выражение массива является операндом
sizeof
(sizeof arr
дает размер массива, а не размер указателя);
- Когда выражение массива является операндом унарного
&
(&arr
является указателем на массив, а не указателем на указатель); а также
- Когда выражение массива является строковым литералом, используемым для инициализации объекта типа массива (
char s[] = "hello";
инициализирует s
как массив, а не как указатель).
Ни один из этих случаев (или других случаев, встречающихся в C++) не появляется в вашей программе, поэтому ваш вызов:
f2(data,ptr);
передает два значения указателя типа char*
на f2
.
Внутри f2
объекты параметров x
и y
имеют тип char*
, поэтому std::is_same<decltype(x), decltype(y)>::value
истинно.
Но типы ar
и pr
различны. ar
— тип неполного массива char[]
, а pr
— тип указателя char*
.
Что объясняет вывод вашей программы. Странность возникает из-за того, что параметр x
, который вы определили с типом массива ar
, на самом деле имеет тип char*
, который совпадает с типом pr
.
person
Keith Thompson
schedule
05.09.2013
T
» или «функция, возвращающаяT
». быть «указателем наT
» или «указателем на функцию, возвращающуюT
» соответственно. Следовательно,decltype(x)
является указателем наchar
, а не массивом неизвестных границchar
(в отличие отar
). - person dyp   schedule 05.09.2013