Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ - Are there ways to get current class type with invariant syntax? [duplicate]

I want to write a macro which, when expanded within a class, uses that class type (specifically, as template argument). Within class method, I can use this:

#define METHOD_MACRO int sample_method(void)const {\
    return template_struct<this_type<decltype(this)>::type>::index;}

(this_type is my struct, here it's equivalent to remove_pointer<remove_const<T>>)

But when I need class type outside of method (for typedef for class member pointer), this keyword isn't available; I've tried to use auto for some trick with deducing type, but no luck here. Classes in question are inherited from my class, if this can be of any help. I would like to avoid anyone using my macro having to write obligatory typdedef.

Any ideas?

like image 242
Abstraction Avatar asked Oct 20 '15 07:10

Abstraction


1 Answers

You can use the following trick:

#define SELF \
    static auto helper() -> std::remove_reference<decltype(*this)>::type; \
    typedef decltype(helper()) self

struct A {
    SELF;
};

I declare a helper function using the auto return type, which allows me to use decltype(*this) as a return type, not knowing what is the class name. Then I can use decltype(helper()) to use the class type in the code. Note that the function has to be static, otherwise you can not use it in decltype. Also the function is just declared, not defined; this should not be a problem as you are not going to call it anyway. (You can add an empty body to it, but it will raise a warning that a function has no return. Still you may change the return type to be decltype(this) and return nullptr.)

You may then use the self typedef for further declarations, or just alter the macros to typedef not the class itself, but what you need to. Adjust it to suit your particular need.

UPD: This seems to be a non-standard behavior of GCC. For example, ICC does not allow this in static functions even in trailing return type.

like image 109
Petr Avatar answered Sep 19 '22 12:09

Petr