Я пишу это как отдельный ответ, а не просто комментарий, потому что я не согласен с ответом Люка Турэля не по причинам законности, а из-за надежного программного обеспечения и опасности неправильного толкования.
В частности, у меня есть проблема с подразумеваемым соглашением о том, что вы ожидаете, что пользователи вашего интерфейса должны знать.
Если вы возвращаете или принимаете ссылочные типы, то вы просто говорите, что они могут проходить через указатель или ссылку, которые, в свою очередь, могли быть известны только через предварительное объявление.
Когда вы возвращаете неполный тип X f2();
, вы говорите, что вызывающий абонент должен иметь полную спецификацию типа X. Он нужен им для создания LHS или временного объекта на сайте вызова.
Точно так же, если вы принимаете неполный тип, вызывающий должен создать объект, который является параметром. Даже если этот объект был возвращен функцией как другой неполный тип, сайту вызова необходимо полное объявление. то есть:
class X; // forward for two legal declarations
X returnsX();
void XAcceptor(X);
XAcepptor( returnsX() ); // X declaration needs to be known here
Я думаю, что существует важный принцип, согласно которому заголовок должен предоставлять достаточно информации для его использования без зависимости, требующей других заголовков. Это означает, что заголовок должен быть включен в модуль компиляции, не вызывая ошибки компилятора при использовании любых функций, которые он объявляет.
Кроме
Если эта внешняя зависимость является желательным поведением. Вместо использования условной компиляции у вас может быть хорошо документированное требование, чтобы они предоставляли свой собственный заголовок, объявляющий X. Это альтернатива использованию #ifdefs и может быть полезным способом введения имитаций или других вариантов. .
Важным отличием является то, что некоторые методы шаблонов, в которых вы явно НЕ ожидаете их создания, упоминаются только для того, чтобы кто-то не стал язвить меня.
person
Andy Dent
schedule
06.07.2013