Is it possible to write a trait, which results the type of the class it is used in? How to implement get_class in the example below?
class Foo {
typedef get_class::type type; // type = Foo now
};
Note: I have to write a macro, which expands in the class body, used for multiple classes, so I cannot simply write 'typedef Foo type;'
Use case:
I have a reflectable(...) macro which generates infrastructure to iterate over members, visit them and look them up using their names:
class Foo
{
friend std::ostream &operator<<(std::ostream &, const Foo&);
reflectable(
(int) bar,
(double) baz
)
}
reflectable(...) should be a macro so I can get the types and member names separately as strings to build maps for the lookup.
I would like all reflectable class to be streamable, but if I put my reflectable() macro to private section, I have to add the friend declaration to the class. I would like to move it to the macro as:
friend std::ostream &operator<<(std::ostream &, const get_class::type&);
I'm sorry, but I'm pretty sure that in standard C++ there is no way around you having to pass in the class name to the macro one way or another. For some failed attempts, see the end of this answer.
That said, I think your best bet is to slightly change your design. Instead of
friend std::ostream &operator<<(std::ostream &, const get_class::type&);
provide a public member function
void stream_to (std::ostream &) const {
// Implementation
}
together with a free function template
template<typename T, typename std:: enable_if<has_stream_to<T>::value>::type * = nullptr>
std::ostream &operator<<(std::ostream & s, T const & t) {
t.stream_to(s);
return s;
}
in your libraries/programs namespace. (Note: I'll add the trait has_stream_to
later, for the impatient search for "detect member function" within C++ tag)
Approaches that don't work:
Use a pointer to member function, extract the class type with a template function. Reason: &foo
inside of a class with a member function foo
won't give a member function pointer to foo
. The syntax is required (by the standard) to be &C::foo
(where C
is the class name...).
Use a pointer to data member, extract the class type with a template function. Same reason as above.
Use a dedicated member function that returns *this
, deduce the return type to get the class type. Reason: Need an instance to call this function on.
Use a pointer to a static member function. Reason: Such pointers are same as pointers to free functions, the class name cannot be deduced from them.
Use the this
pointer in a member initialisation. Reason: type of member needs to encode class type somehow, but auto
is not allowed for non static data members.
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