#include #include #include template class uart_interface { public: void init(std::uint32_t baudrate = 9600) { static_cast(this)->initImpl(baudrate); } void write(std::span data) { static_cast(this)->writeImpl(data); } }; class uart_stm32 : public uart_interface { public: void initImpl(std::uint32_t baudrate = 9600) { printf("uart_stm32::init: setting baudrate to %d\r\n", baudrate); } void writeImpl(std::span data) { printf("uart_stm32::write: "); for(auto ch: data) { putc(ch, stdout); } } }; template concept TheUart = std::derived_from>; template class gsm_lib{ public: gsm_lib(T &u) : uart_(u) {} void init() { printf("gsm_lib::init: sending AT command\r\n"); uart_.write("AT"); } private: T &uart_; }; int main() { uart_stm32 uart_stm32_obj; uart_stm32_obj.init(115200); gsm_lib gsm(uart_stm32_obj); gsm.init(); return 0; }