3 ms·
Is there a template alternative? Whenever macros seem essential in C++, there's usually a better way without macros.
by jordigh 11y ago
Is there a template alternative? Whenever macros seem essential in C++, there's usually a better way without macros.
- usefulcat 11y agoIf there is I'd love to see it. But I'm fairly certain there's no way to do what he's doing with templates.
- striking 11y agoAlso, templates can be visually unappealing and slow to compile. (Of course, these are generalizations, and only how they work without particular care.)
- Rexxar 11y agoThere is a reflection group "SG7" in c++ committee dedicated to this. Some propositions have been done. I hope it will be ready for c++17. Group discussions : https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/reflection https://groups.google.com/a/isocpp.org/forum/?fromgroups#!fo... One proposition : http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4113.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n411...
- MereInterest 11y agoFor some of these, yes. For others, less so. Each one has their limitations. For the AstVisitor, you could make a templated class AstVisitor<T>. You would then derive AstVisitor<BoolLiteral> in order to have a class that only visits particular node types. template<typename T> class AstVisitor : public GenericAstVisitor { // Implements GenericAstVisitor::Visit virtual void Visit(AstNode* expr) { T* t_expr = dynamic_cast<T*>(expr); if(t_expr){ Visit(t_expr); } } virtual void Visit(T* expr) = 0; }; If you need to visit multiple node types, then you would need to head into variadic templates. Here, you would inherit from AstVisitor<BoolLiteral, NumLiteral>, then implement a visitor for each type. template<typename... T> class AstVisitor; template<typename First, typename... Rest> class AstVisitor<First, Rest...> : public AstVisitor<Rest...> { virtual void Visit(AstNode* expr) { First* f_expr = dynamic_cast<First*>(expr); if(f_expr){ Visit(f_expr); } else { AstVisitor<Rest...>::Visit(expr); } } virtual void Visit(First* expr) = 0; }; template<> class AstVisitor<> : GenericAstVisitor { virtual void Visit(AstNode*) { } }; For the enums and switch statements, I don't know of any way to get away from using macros. There have been some proposals for C++17 to include compile-time reflection, but until then, we're stuck with the macros.
- mattnewport 11y agoYou can do some similar things with boost Fusion and the forthcoming boost Hana which primarily use templates but still use some convenience macros to declare those templates. Both these libraries let you work with lists of types in various ways but I don't know of any template replacements for stringizing and token pasting in the preprocessor, both of which come in very handy for this sort of thing.