Я конвертировал эти таблицы строк документации (как черты типа, такие как система) для некоторых классов объектов домена, пока не наткнулся на эту проблему.
Позже я планировал проверить во время компиляции, была ли написана документация для этих специальных членов (в качестве причины, по которой я хотел бы получить ее во время компиляции).
Я создал небольшой пример для демонстрации:
https://godbolt.org/z/3dX3-e
#include <initializer_list>
struct CStr {
struct M {
const char* name;
const char* val;
};
constexpr CStr(const std::initializer_list<M>& str) : str_(str) {
};
std::initializer_list<M> str_;
};
constexpr CStr cstr_test{ { {"key", "val"} } };
int main() {
return cstr_test.str_.begin()->name[0];
}
В основном 3 основных компилятора, похоже, по-разному относятся к этому случаю, этот , по-видимому, работает на более старом gcc , но не может скомпилироваться при переходе на последнюю версию 9.1 (например, строку cstr_test не является постоянным выражением). На msvc ( и на тот, который заинтересован в ) initializer_list
получает правильный размер, но временный не сохраняется на выходе. clang отказался от компиляции из-за временного создания. Эта последняя вещь кажется намеком, и я подозреваю, что это может происходить и с msvc , но без сообщения об ошибке.
Пример можно исправить, если изменить std::initializer_list<M>
на M
.
Соответствующим разделом из справочника может быть:
Базовый массив - это временный массив типа const T [N], в котором
каждый элемент инициализируется копией (за исключением того, что сужающие преобразования
недопустимы) из соответствующего элемента оригинала
список инициализаторов. Время жизни базового массива такое же, как
любой другой временный объект, кроме инициализации
Объект initializer_list из массива продлевает время жизни
массив точно так же, как привязка ссылки к временному (с тем же
исключения, например, для инициализации нестатического члена класса).
базовый массив может быть размещен в постоянной памяти.
Как создать список объектов, содержащих строки, во время компиляции?