3 ms·
I'm not necessarily going to defend proc macros, which have a lot of problems but are also better than the alternative in many languages (like Go's over-relianc
by necubi 2y ago
I'm not necessarily going to defend proc macros, which have a lot of problems but are also better than the alternative in many languages (like Go's over-reliance on codegen). Macros-by-example are pretty nice though, even with the special syntax.
But in Rust, you don't need to delve into any kind of macro for polymorphism like you do in C++, since Rust has a real generics system. There is vastly more C++ code that instantiates templates than Rust code that uses macros.
- pjmlp 2y agoThere are enough ways to do polymorphism in C++ without touching macros. Given that Rust IO and many crate attributes are macro based, not sure who wins out.
- necubi 2y agoI was a bit unclear there—I was referring to templates, not C++ macros. I believe that concepts in C++20 have improved the situation (although I haven't personally worked with a C++20 codebase and don't know how widely adopted it is in the ecosystem).
- pjmlp 2y agoStill there is no need for macros. The only thing you may complain about are error messages due to duck typing at compile time gone wrong, and even that is kind of already sorted out in C++17. Anyway, C++ today means C++23.
- pjmlp 2y agoC++17 example, showing polymorphism at compile time without macros. Naturally checking for speak() existence with enable_if, static_assert and type traits could be added, though this is an example, and nowdays we would make use of concepts anyway. #include <iostream> using namespace std; class Duck { public: void speak() const { cout << "quack"; } }; class Dog { public: void speak() const { cout << "auau"; } }; class Cat { public: void speak() const { cout << "miau"; } }; template<typename T> void speaking_animal(const T& animal) { animal.speak(); cout << "\n\n"; } template<typename... T> void speaking_farm(const T&... animals) { auto space_adder = [&](auto creature) -> void { creature.speak(); cout << " "; }; (space_adder(animals), ...); } int main() { Duck duck; Dog dog; Cat cat; speaking_animal(duck); speaking_animal(dog); speaking_animal(cat); speaking_farm(duck, dog, cat); } Available at https://godbolt.org/z/WWfx5jWfM https://godbolt.org/z/WWfx5jWfM
- cherryteastain 2y agoIn modern C++, you don't need macros for polymorphism at all
- marginalia_nu 2y agoUnless this is about some particular technique I've missed, isn't this what virtual methods are for? Only place I'm aware of where you see macros-based polymorphism is in C.
- cherryteastain 2y agoVirtual methods are runtime polymporphism. Templates are compile time polymorphism, and therefore typically are faster (more inlining + avoiding virtual function call).
- pjmlp 2y agoNo need for macros in compile time polymorphism.