Как работает инициализатор std::array для char?

Я не уверен, как работает следующий код. Я думал, что вам нужно сделать {'h', 'e' ...etc...}, но, похоже, это работает нормально. С другой стороны, если вы сделаете std::array<const char*, он добавит только один элемент в массив. Существуют ли специальные правила для инициализации строкового литерала?

std::array<char, strlen("hello world!") + 1> s = {"hello world!"};
for (size_t i = 0; i < s.size(); ++i)
{
    std::cout << s[i];
}

person user4051846    schedule 17.09.2014    source источник


Ответы (2)


Класс std::array является агрегатом. В этом заявлении:

std::array<char, strlen("hello world!") + 1> s = {"hello world!"};

используется инициализация списком. Поскольку первым и единственным элементом этого экземпляра класса std::array является массив символов, он может быть инициализирован строковыми литералами.

Вместо функции strlen было бы правильнее использовать оператор sizeof:

std::array<char, sizeof( "hello world!" )> s = {"hello world!"};

Также вы могли бы написать

std::array<char, sizeof( "hello world!" )> s = { { "hello world!" } };

потому что массив символов, в свою очередь, является агрегатом.

Согласно стандарту С++

8.5.2 Массивы символов [dcl.init.string]

1 Массив узкосимвольного типа (3.9.1), массив char16_t, массив char32_t или массив wchar_t может быть инициализирован узким строковым литералом, char16_t строковым литералом, char32_t строковым литералом или широким строковым литералом, соответственно, или соответствующим строковый литерал, заключенный в фигурные скобки (2.14.5). Последовательные символы значения строкового литерала инициализируют элементы массива.

[ Пример:

char msg[] = "Syntax error on line %s\n";
person Vlad from Moscow    schedule 17.09.2014

Вот способ достижения этого

// GOAL
std::array<char, sizeof("Hello")> myarray = {"Hello"};

т.е. инициализация std::array строковым литералом (да, использовался макрос)

// SOLUTION
#define STD_CHAR_ARRAY_INIT(arrayname, string_literal) /*std::array*/<char, sizeof(string_literal)> arrayname = {string_literal}
std::array STD_CHAR_ARRAY_INIT(myarray, "Hello");

Вот некоторый тестовый код:

#include <iostream>
#include <array>

using std::cout;
using std::ostream;

template<typename T, size_t N>
std::ostream& std::operator<<(std::ostream& os, array<T, N> arr)
{
  {
    size_t cnt = 0;
    char strchar[2] = "x";
    for (const T& c : arr) {
      strchar[0] = c;
      os << "arr[" << cnt << "] = '" << (c == '\0' ? "\\0" :  strchar /*string(1, c)*/  ) << "'\n"
         << '.' << c << '.' << '\n';
      ++cnt;
    }
  }
  return os;
}


#define STD_CHAR_ARRAY_INIT(arrayname, string_literal) /*std::array*/<char, sizeof(string_literal)> arrayname = {string_literal}

int main()
{
  std::array STD_CHAR_ARRAY_INIT(myarray, "Hello");
  cout << myarray << '\n';
  return 0;
}
person Mike    schedule 14.12.2014