Почему «ссылка на массив» определена в C ++ таким странным образом? - PullRequest
3 голосов
/ 23 июня 2011

Следующий код основан на фрагменте отсюда .Я хочу шаблонную функцию, которая принимает ссылку на массив размера, который выводится при создании экземпляра функции:

template<int size>
void myFunction( SomeType(&param)[size] )
{
    //use param and size here
}

//called like this:
SomeType array[SomeConstant];
myFunction( array ); //SomeConstant magically gets into the function as "size"

Теперь я путаюсь с SomeType(&param)[size].Я ожидаю, что сработает следующее:

template<int size>
void myFunction( (SomeType[size])& param ) {}

, но оно не скомпилируется.

Зачем мне нужен такой странный синтаксис для "ссылки на массив фиксированного размера"?

Ответы [ 4 ]

4 голосов
/ 23 июня 2011

Он основан на синтаксисе объявления C. Конечно, C не имеет ссылок, но он предназначен для имитации синтаксиса C для указателей. Вот указатель на массив (в C или C ++):

int (*parray)[size];

Идея состоит в том, что объявление имитирует использование. Предполагается, что позже, когда вы используете parray, выражение

(*parray)[0]

(или любой другой индекс) имеет тип int. Конечно, симметрия нарушается для ссылочных типов, поскольку & используется при их объявлении, но не на них.

3 голосов
/ 23 июня 2011

Это для согласованности с синтаксисом объявления массива C.

С вашим предложенным синтаксисом вы также напишите:

int*[4] x;

вместо

int* x[4];

Этонеплохой выбор, но это не то, что использует C, а C ++ пытается быть совместимым.

1 голос
/ 23 июня 2011

При объявлении вы должны следовать правилу:

Начните с названия, идите направо, когда можете, и идите налево, когда должны.

это правило полностью описано в этой полезной ссылке, а & обрабатывается как *, это ссылка:

http://unixwiz.net/techtips/reading-cdecl.html

При удалении вы ставите [] перед именем переменной, что недопустимо. Правило состоит в том, что каждые * и & должны идти перед именем, а каждые [] и () должны идти после имени.

1 голос
/ 23 июня 2011

Проблема с вашим вторым объявлением заключается в том, какое значение следует использовать в качестве идентификатора?Это должно быть param или SomeType?Из-за круглых скобок первая часть объявления будет проанализирована первой, но если это так, и SomeType не был идентификатором, то в какой момент при синтаксическом анализе идентификатор получает имя?

Использование шаблона синтаксического разбора по часовой стрелке в C / C ++, где идентификатором является самый неизвестный анализируемый элемент (т.е. что-то, что не является известным токеном или ключевым словом ... см. Ссылку), синтаксискак

(SomeType[size])& param

будет читать «SomeType - это массив фиксированного размера, который является типом ссылочного типа для некоторого объекта param», что, конечно, не имеет никакого смысла, так как массив не имеетбыл объявлен с типом объекта, который является массивом.С другой стороны,

SomeType(&param)[size]

, использующий те же правила синтаксического анализа, будет читать «param - это ссылка на массив фиксированного размера, который содержит объекты типа SomeType».Последнее, конечно, объявление, которое вы хотите, и что имеет смысл для синтаксического анализатора C / C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...