Страницы

Поиск по вопросам

четверг, 20 декабря 2018 г.

Использование this в методах классов

Есть вот такой код:
template struct somestruct { ...
T somefunction(somestruct* const th = this) { return th ? th->somefield1 : this->somefield2; }
... };
Компилятор VS 2017 ругается:
Ошибка C2355 "this": может указываться только в нестатических членах-функциях или инициализаторах нестатических членов данных
Объясните пожалуйста, почему я не могу подобным образом использовать this?
Я хотел бы, чтобы вызов somepointer->somefunction(otherpointer) возвращал поле объекта указателя из аргумента, если он не nullptr, иначе возвращал другое поле объекта указателя, вызвавшего метод. А если somefunction вызывается без аргументов, то это было бы аналогично вызову somepointer->somefunction(somepointer). Конечно, можно делать такой вызов явно или просто перегрузить somefunction, но интересно, почему нельзя так, как я написал.


Ответ

Короткий ответ: потому что в стандарте языка сказано, что так нельзя.
Длинный ответ: в языке С++ не допускается формирование значений аргументов по умолчанию на основе параметров функции.
void foo(int a, int b, int c = a + b) // Ошибка { ... }
this - это тоже неявный параметр нестатического метода класса, поэтому использовать его для формирования значения аргумента по умолчанию не дозволяется. Причина этого заключается, в частности, в том, что это привело бы в необходимости вычислять параметры функции в некотором "правильном" порядке, а язык С++ не упорядочивает и никогда не упорядочивал вычисление параметров.† Это может быть не единственной причиной такого запрета.
Вместо аргумента по умолчанию вы можете просто использовать перегрузку и получить требуемый эффект
template struct somestruct { ...
T somefunction(somestruct* const th) { return th ? th->somefield1 : this->somefield2; }
T somefunction() { return somefunction(this); }
... };

† Начиная с С++17 вычисление аргумента для неявного параметра this упорядочено перед вычислением всех остальных аргументов. Теоретически, это должно было бы устранить вышеописанную проблему с порядком вычисления, но пока что это не привело к изменениям в спецификации использования this в аргументах по умолчанию.

Комментариев нет:

Отправить комментарий