Can somebody please break down this for me? I know macros, and I am fairly familiar with templates, but I have no idea what the author is expressing with this. What's the intended usage, why is it written like this? What are we defining to be what here? How and why does one use this?
#define MY_CLASS(RET_TYPE, ... )\
template<typename Derived>\
__VA_ARGS__\
RET_TYPE my_class_impl<Derived>
And I also have something like
MY_CLASS( )::my_class_impl( int arg_id )
And I also see
template<typename Derived>
class my_class_impl
I heard from a colleague that this is a case of CRTP (curiously recurring template pattern), but he did not have any more specific insights.
Also, I see it used subsequently as follows:
MY_CLASS(some_type)::find_desired_val(int x) {
// some code
}
So, the macro is used to substitute method signatures for the class my_class_impl
when actually implementing them?
It's used to define member functions of my_class_impl<Derived>
.
MY_CLASS(void)::member(Bar b) {}
Expands to :
template <typename Derived>
void my_class_impl<Derived>::member(Bar b) {}
The variadic macro arguments can be used for various (standard or not) attributes, such as __declspec(...)
, [[...]]
, etc. For example:
MY_CLASS(void, __declspec(dllexport))::foo();
Expands to :
template <typename Derived>
__declspec(dllexport) void my_class_impl<Derived>::foo() {}
The MY_CLASS()::my_class_impl(int arg_id)
, thanks to a compiler extension that allows missing macro parameters (present on MSVC, as well as Clang and GCC, I was mistaken), expands to a constructor :
template <typename Derived>
/* nothing */ my_class_impl<Derived>::my_class_impl(int arg_id) {}
It is also quite an ugly macro. Not only is it hard to understand, it hides away very mundane stuff, and breaks if you ever try to return a type containing a comma (std::map<int, int>
).
The RET_TYPE
is a hint that this is a function, and MY_CLASS
in particular hints at member functions. Those can be declared static
as well.
Less common would be [[noreturn]]
or [[deprecated]]
which are C++14 attributes.
The <Derived>
part is pretty irrelevant to this, class templates can have member functions just like classes can.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With