Каково обоснование поведения decltype?
как я понял в C++11 decltype(expression)
используется для вывода точно такого же типа данного выражения. Но когда выражение заключено в скобки само по себе, то выводит тип ссылка lvalue тип выражения. Например:
int x;
decltype(x) y = x;
эквивалентно int y = x;
а,
int x;
decltype((x)) y = x;
эквивалентно int& y = x;
.
соответственно
decltype(auto) f1()
{
int x = 0;
return x; // decltype(x) is int, so f1 returns int
}
но
decltype(auto) f2()
{
int x = 0;
return (x); // decltype((x)) is int&, so f2 returns int&
}
каково обоснование для такое поведение должно быть выбрано стандартным комитетом?
послесловия:
я заметил, что, по крайней мере, в случае GCC 6.2 реализация, когда выражение в скобках является более сложным, напримерdecltype((x + x))
выводимый тип T
, но не T&
. Это еще больше сбивает с толку. Я не знаю, является ли это поведение является стандартным.3 ответа:
они хотели способ получить тип объявления идентификатора.
они также хотели получить способ получить тип выражения, включая информацию о том, является ли оно временным или нет.
decltype(x)
дает объявленный тип идентификатораx
. Если вы пройдетеdecltype
что-то, что не является идентификатором, он определяет тип, а затем добавляет&
для lvalues,&&
для xvalues, и ничего для prvalues.концептуально вы можете думать о это как разница между типом переменной и тип выражения. Но это не совсем так, как описывает стандарт.
они могли бы использовать два разных ключевых слова, чтобы означать эти две вещи. Они этого не сделали.
существует некоторая потребность в различении между сущностью и выражением.
рассмотрим следующий вопрос:
как долго это Миссисипи?
на этот вопрос есть два ответа:
- Миссисипи составляет 2320 миль в длину.
- Миссисипи-это 11 букв.
аналогично, когда вы спрашиваете о типа
x
иx
- это идентификатор, непонятно если вы имеете в виду тип, который был использован для объявления этого идентификатора (т. е. тип, связанный с именемx
), или тип выражения, состоящего из единственного упоминания этого идентификатора. На самом деле может быть два разных ключевых слова (например,entity_type
иexpr_type
) вместо одного перегруженногоdecltype
. По какой-то причине комитет решил перегрузитьdecltype
для этих двух разных целей.
от одного из авторов
decltype
предложение, Дж. Ярви:это было некоторое время, но вот что я (думаю, что я) помню:
два отдельных ключевых слова для дифференциации этих двух видов семантики никогда не рассматривался. (Введение новых ключевых слов не делается легко).
что касается изменения семантики
decltype((x))
, обсуждение в основная рабочая группа сошлась на лечении(x)
как выражение, а чем идентификатор, который, возможно, является более " внутренне согласованным" с языковыми правилами.люди знали, что это потенциально может привести к путанице в некоторых случаи, но консенсус (хотя, возможно, не все предпочтения) был в конечном счете, чтобы соответствовать предыдущему определению стандарта что такое идентификатор и что такое выражение.
пример, который вы ссылаетесь на [пример этого вопроса], действительно удивителен. В то время, выводящая функция возвращаемый тип из возвращаемого выражения с помощью
decltype(auto)
еще не было частью языка, поэтому я не думаю, что это конкретное использование дело было у всех на виду.