Ответ 1
Кажется, проблема заключается не в том, что this
появляется внутри decltype
, но что он выглядит вне тела функции.
Для example этот код ниже компилируется под GCC 4.7:
struct A
{
int f() { return 0; }
auto g() -> decltype(f()) {
decltype(this->f()) var = this->f();
return var;
}
};
Это использует decltype(this->f())
внутри тела g
, но спецификация возвращаемого типа функции в форме auto .... -> ....
, т.е. так называемая спецификация trailing return type не является частью тела функции, и GCC не позволяет его там.
Однако, казалось бы, (см. обсуждение в комментариях), что стандарт С++ фактически не требует использования this
в теле функции: §5.1.1 стандартных состояний, что this
может использоваться где угодно между необязательным спецификатором const/volatile и концом тела функции, см. раздел 3 ниже. (Для полноты я добавил также пункт 4, в котором говорится о членах данных и не имеет прямого отношения к вопросу).
(Статья 3) Если объявление объявляет функцию-член или шаблон функции-члена класса X, выражение thisявляется prvalue типа "указатель на cv-quali fi-seq X" между необязательным cv-qualifer-seq и концом функция-определение, член-декларатор или декларатор. Он не должен появляться перед дополнительным cv-quali-fi-seqи он не должен появляться в объявлении статической функции-члена (хотя его тип и значение категории определяются в рамках статической функции-члена, поскольку они находятся в нестатической функции-члене). [...]
(раздел 4) В противном случае, если декларатор-член объявляет нестатический элемент данных (9.2) класса X, выражение this является prvalue типа "указатель на X" внутри необязательного выравнивающего или равного инициализатора. Он не должен появляться в другом месте в объявлении участника.
(Пункт 5) Выражение this не должно появляться ни в каком другом контексте. [...]
NB: необязательный cv-qualifier-seq, то есть спецификатор const
или volatile
для функции должен, как указывает Джесси в комментарии, выглядеть перед объявлением возвращаемого типа возврата. Следовательно, использование this
способом, описанным в вопросе, должно быть правильным, а GCC кажется неправильным.