В следующей реализации static_strlen зачем нужны & и круглые скобки вокруг str? - PullRequest
3 голосов
/ 02 апреля 2010

Если я изменяю тип на const char str[Len], я получаю следующую ошибку:

error: no matching function for call to ‘static_strlen(const char [5])’

Правильно ли, что static_strlen ожидает массив константных символов ссылок ? Насколько я понимаю, массивы передаются как указатели в любом случае, так зачем нужны элементы для ссылок? Или эта интерпретация совершенно не соответствует действительности?

#include <iostream>

template <size_t Len>
size_t
static_strlen(const char (&str)[Len])
{
  return Len - 1;
}

int main() {
  std::cout << static_strlen("oyez") << std::endl;
  return 0;
}

Ответы [ 2 ]

4 голосов
/ 02 апреля 2010

Нет, параметр функции является ссылкой на массив Len const символов. Вот как функция знает длину (при условии, что последний байт является NUL-терминатором, следовательно, -1). Скобки предназначены именно для того, чтобы это не было так, как вы думаете.

На самом деле в C ++ нет такого понятия, как массив ссылок, поэтому он не может быть тем, о чем вы думаете, даже без паренов. Я предполагаю (но не уверен), что необходимость в паренонах нужна только для согласованности с другими аналогичными определениями типов, такими как указатели на массивы:

void fn(const char *a[3]); // parameter a is of type const char**, the 3 is ignored.
void fn(const char (*a)[3]; // parameter a is a pointer to an array of 3 const chars.

Этот пример также показывает, почему массив не является указателем. Спрогнозируйте вывод следующей программы и запустите ее:

#include <iostream>

void fn(const char (*a)[3]) {
    std::cout << sizeof(a) << "\n" << sizeof(*a) << "\n";
}

void fn2(const char *a[3]) {
    std::cout << sizeof(a) << "\n" << sizeof(*a) << "\n";
}

int main() {
    const char a[3] = {};
    const char **b = 0;
    fn(&a);
    fn2(b);
}

#if 0 
// error: declaration of `a' as array of references
void fn3(const char & a[3]) {
    std::cout << sizeof(a) << "\n" << sizeof(*a) << "\n";
}
#endif
0 голосов
/ 02 апреля 2010

Это один из способов сделать функцию такой, что размер массива передается в функцию автоматически.

static_strlen(const char (&str)[Len])

- это функция, которая принимает в массиве const char ровно Len элементов. Размер массива должен быть известен во время компиляции. То есть массив не был выделен через new или malloc.

Точнее говоря, параметр является ссылкой на массив Len элементов, а не на фактический массив, поэтому он не преобразуется в указатель при передаче.

...