Разрешено ли использовать decltype в инициализаторе для переменной decltyped? - PullRequest
3 голосов
/ 24 марта 2020

По запросу этот вопрос , мне было интересно, разрешено ли это:

template <typename T>
T foo(){return T{};}

struct bar {};

int main()
{

    bar a = foo<decltype(a)>();
}

Компиляторы, которые я пробовал, приняли его без нареканий, но я не уверен, действительно ли это законно или если я пропускаю какие-либо ловушки (и кажется странным использовать тип a во время его объявления).

Для фона: в связанном вопросе OP хочет избежать auto и дважды указывать тип (здесь это bar, SomeComplexTypeAndNotAuto в этом вопросе), следовательно, они используют (неиспользованный) параметр для вывода T. Мне не нравилось неправильно использовать параметр просто для вывода типа, поэтому моей первой идеей было decltype.

1 Ответ

9 голосов
/ 24 марта 2020

Все в порядке.

[basi c .scope.pdecl]

1 Точка декларации для имя сразу после его полного декларатора ([dcl.decl]) и до его инициализатора (если есть), за исключением случаев, указанных ниже. [Пример:

unsigned char x = 12;
{ unsigned char x = x; }

Здесь инициализация второго x имеет неопределенное поведение, поскольку инициализатор получает доступ ко второму x вне его времени жизни ([basi c .life]). - конец примера]

Таким образом, вы можете использовать a в своем собственном инициализаторе, поскольку он объявлен в точке. Вопрос только в том, как. decltype может быть применено к id-выражению с именем любой переменной в области видимости. А так как выражение decltype является неоцененным операндом , UB отсутствует. Проверяется только тип переменной, а не ее неопределенное значение.

Хотя вкуса не учитывается.

...