Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting type of "this" in C++ when defining non-static member

I'm trying to do some fancy template stuff and I've stumbled on a problem: I would like to get the type of a class, inside its definition, while defining a non-static member. Is this possible? (In any C++ version.)


Take the following code:

template<typename T>
struct inner {
    T* this_;
    /* fancy stuff... */
};

struct foo {
    inner<foo> bar{this};
};

The class foo has a non-static member bar that is initialized with the pointer foo* this. This code compiles in clang and gcc.

But I actually want the definition of inner to appear in a macro, which means I don't have the string foo to use in the line inner<foo> bar{this}. Trying to use:

inner bar{this};

in C++17, which allows template argument deduction for class templates, produces the error

error: use of class template 'inner' requires template arguments; argument deduction not allowed in non-static struct member inner bar{this};

which I understand. Trying:

inner<decltype(*this)> bar{this};

produces a similar looking error:

error: invalid use of 'this' outside of a non-static member function inner<decltype(*this)> bar{this};


As a workaround, I've been using the following curiously recurring template pattern:

template<typename T>
struct SelfAwareType {
    using myOwnType = T;
}

struct foo : SelfAwareType<foo> {
    inner<myOwnType> bar{this};
};
like image 535
Dror Speiser Avatar asked Nov 07 '22 06:11

Dror Speiser


1 Answers

If you can constrain all foo's to require a typedef 'this_type' then your macro could be free of needing to specify foo.

template<typename T>
struct inner {
    T* this_;
    /* fancy stuff... */
};

struct foo {
    typedef foo this_type ;
    inner<this_type> bar{this};
};

which is basically the same as your 'workaround' without having to use crtp and introduce another type.

like image 93
rmawatson Avatar answered Nov 14 '22 22:11

rmawatson