Возврат по значению не требует определения типа. Предварительного объявления достаточно
Объявление функции, возвращающей значение, не требует определения типа. Хорошо сформированная демонстрация:
struct S;
S foo();
struct S {};
int main() {
foo();
}
S foo() {
return {};
}
Определение или вызов функции, которая возвращает значение, требует определения типа. Стандартный черновик [basic.def.odr]:
5 В единице перевода требуется ровно одно определение класса, если класс используется таким образом, что требуется, чтобы тип класса был полным. [ Пример: ... [отрезок] ... [ Примечание. Правила для объявлений и выражений описывают, в каких контекстах требуются полные типы классов. Тип класса T должен быть полным, если:
- [отрезать]
- 5.9 функция с типом возвращаемого значения или типом аргумента типа T определена ([basic.def]) или вызвана ([expr.call]), или
- [отрезать]
Объявление функции с неполным типом возвращаемого значения неявно разрешено в силу того, что оно не запрещено ни одним из правил в списке.
Правило переформулировано позже в стандарте и смягчено исключением [dcl .fct] (спасибо @cpplearner за указание на это правило):
11 Типы не должны определяться в возвращаемых типах или типах параметров. Тип параметра или тип возвращаемого значения для определения функции не должен быть неполным (возможно, cv-квалифицированным) типом класса в контексте определения функции, если функция не удалена ([dcl.fct.def.delete]).
Плохо сформированная демонстрация:
struct S;
S foo() {
return {};
} // oops
struct S {};
Еще одна плохо сформированная демонстрация:
struct S;
S foo();
int main() {
foo(); // oops
}
struct S {};
S foo() {
return {};
}
person
eerorika
schedule
31.01.2017