Может ли строковый литерал быть подписан в постоянном выражении?

Это действительно, поскольку экспрессия CONSTEXPR разрешено принимать значение «Tlvalue буквального типа, которое относится к на ненулительную объект, определенный с constexpr, или это относится к подзерцезнику такого объекта "(§5.19 / 2):

constexpr char str[] = "hello, world";
constexpr char e = str[1];

Тем не менее, казалось бы, что строковые литералы не соответствуют этому описанию:

constexpr char e = "hello, world"[1]; // error: literal is not constexpr

2.14,5 / 8 описывает тип строковых литералов:

Обычные строковые литералы и строковые литералы UTF-8 также называют узкими строковыми литералами. Узкая строка литерала имеет тип «массив N Const Char», где n - это размер строки, как определено ниже, и имеет статический длительность хранения.

Кажутся, что объект этого типа может быть проиндексирован, если только это временно, а не с длительностью статического хранения (5,19 / 2, сразу после вышеуказанного фрагмента):

[ [ CONSTEXPR позволяет преобразовать преобразование Lvalue-rvalue] ... воспоминание буквального типа, который относится к нелетующему временному объекту, срок службы которого не закончился, инициализировался с постоянным выражением

Особенно странно с момента принятия временного объекта, обычно «обмана». Я полагаю, что это правило относится к функционированию аргументов репорционального типа, например, в

constexpr char get_1( char const (&str)[ 6 ] )
    { return str[ 1 ]; }

constexpr char i = get_1( { 'y', 'i', 'k', 'e', 's', '\0' } ); // OK
constexpr char e = get_1( "hello" ); // error: string literal not temporary

для того, что он стоит, GCC 4.7 принимает Get_1 («Hello») , но отклоняет «Привет» [1] , потому что «Значение» ._0 'не используется в постоянном выражении «... И все же « Hello »[1] является , приемлемым в качестве метки регистрации или границ массива.

Я разделяю несколько стандартных волосков здесь ... это анализ правильным, и был ли какой-то дизайн намерения для этой функции?

Редактировать: О ... есть некоторая мотивация для этого. Похоже, что такое выражение является единственным способом использования таблицы поиска в препроцессоре. Например, это представляет собой блок кода, который игнорируется, если que_integer_flag не составляет 1 или 5, а приводит к диагностике, если он превышает 6:

#if "\0\1\0\0\0\1"[ SOME_INTEGER_FLAG ]

Эта конструкция была бы новой для C ++ 11.

17
задан Xeo 27 January 2012 в 19:18
поделиться