Если вы дадите виртуальные функции базового класса, тогда они будут у него. Всегда. Он никогда не может не иметь этих функций, и каждый производный от него класс будет наследовать эти функции.
view_interface
имеет функцию empty
тогда и только тогда, когда категория диапазона для типа forward_range
. То есть empty
существует, если begin
возвращает прямой итератор, а end
возвращает дозор для этого итератора. Но вы можете проверить это только в том случае, если можете запрашивать свойства производного класса. И базовый класс не может этого сделать ... если вы не разрешите ему, указав тип производного класса. Это означает, что это должен быть параметр шаблона, а базовый класс - это шаблон.
И поэтому вы используете CRTP.
Предоставление или отсутствие общих функций на основе категорий итераторов производного класса диапазона - это вся точка класса. Единственная альтернатива - иметь набор базовых классов для каждого типа итератора. Таким образом, у вас будет forward_view_interface
для прямых диапазонов, contiguous_view_interface
для смежных диапазонов и т. Д. И это было бы болезненно. Но начнется мультипликативный взрыв, потому что некоторые свойства, предоставляемые view_interface
, ортогональны категории итератора.
Например, size
предоставляется, если диапазон является диапазоном размеров. Но это может произойти для любой категории итераторов, даже для итераторов ввода. Итак, теперь вам нужно sized_forward_view_interface
и т. Д.
Или вы можете просто использовать CRTP.
person
Nicol Bolas
schedule
08.02.2021
single_view<std::function<void()>>
является владельцем и не совсем легковесным. - person cpplearner   schedule 08.02.2021