Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

equivalence to decltype(*this) from a static method?

Tags:

c++

c++11

I have some macros that need access to the type of the current class and I currently get away with this via a DRY-violating pattern:

struct ThisScruct{
    int a;
    double b;
    //example static method using this - purely example - not full usecase

    static size_t sum_offsets(){
       typedef ThisStruct SelfT;
       return offsetof(SelfT, a) + offsetof(SelfT, b);
    }
};

This comes up a lot with use of the offsetof keyword, at least in my own work.

Now before you lock onto this not being accessible via a static method - realize I just want to know how to get the type ThisStruct in a generic/macro friendly way from a static method context. I don't actually need/want an instance and am looking for way that actually works like the above without typedeffing SelfT.

Edit: Something similar is asked in Can I implement an autonomous self member type in C++? - but I am worried about a diamond problem forming with classes both inheriting from the accepted answer's Self class.

like image 828
Jason Newton Avatar asked May 14 '15 03:05

Jason Newton


1 Answers

You could use the CRT-pattern to access the typename generically, you just need to specify it in the inheritance list.

    template<class T>
struct Type { using type = T; };

struct ThisScruct : Type<ThisStruct> {
    int a;
    double b;

    // this function can be copy-pasted into every
    // struct definition, which is inherited from
    // Type and contains the members a and b
    static size_t sum_offsets(){
       typedef Type::type SelfT;
       return offsetof(SelfT, a) + offsetof(SelfT, b);
    }
};

You might rename Type to a more descriptive name. But you might consider replacing this functionality completely by the CRT-pattern, by moving the functions into the inherited struct.

    template<class T>
struct SumOffsets {
    static size_t sum_offsets(){
       typedef T SelfT;
       return offsetof(SelfT, a) + offsetof(SelfT, b);
    }
};

struct ThisStruct : SumOffsets<ThisStruct> {
    int a;
    double b;
};

The function sum_offsets can be accessed by ThisStruct::sum_offsets, because even static functions are inherited. There is no additional overhead, because neither virtual functions are involved nor SumOffsets has data members.

like image 66
cmdLP Avatar answered Nov 14 '22 12:11

cmdLP