16

I assume this is outright impossible, but what if. Is it possible to somehow get type of enclosing class in a static member function, in any version of C++?

class Impossible {
public:
    static void Fun()
    {
        typedef Impossible EnclosingClass;

        // now do something with EnclosingClass ...
    }
}

Is there a way to get the type of the enclosing class (Impossible in this case) without writing the name of the class in the function?

The reason why I'd like to do that is to avoid repeating the class name in the function. It could easily lead to a hard to find copy-paste bug, if something like this happened:

class SomeOther { // another class, with the same interface as Impossible
public:
    static void Fun()
    {
        typedef Impossible EnclosingClass;
        // whoops, copy-pasted, forgot to change "Impossible" to "SomeOther"

        // now do something with EnclosingClass ...
    }
}

Is there a good way to prevent this kind of thing happening? I could imagine touching something that was declared private in the enclosing class, but that would be forcing me to write extra code (as my current design doesn't contain any inherent private members, all is public).

the swine
  • 10,713
  • 7
  • 58
  • 100
  • 4
    +1 for telling us *why* you want this without having to be poked & prodded. – John Dibling Jan 15 '14 at 16:52
  • @jbgs I'm not sure if I understand how would that help. You mean making the whole Fun() a template? That would make me repeat the class name twice per every call instead of just per declaration. Note that although Run() would be the same most of the time (and hence prone to copy-paste errors), it might differ in some cases, so I think making it a global static function is not a good idea (but then again, template specialization of that function could be used). Was that what you had in mind? – the swine Jan 15 '14 at 16:59
  • 3
    @JohnDibling: What I really find astonishing that no long-timers here started the "but is it *really* that important?" series of comments. Asking questions similar to this is like walking through a brick wall, you not only have to explain why you want to do it but you also have to convince people why *they* would want to do it before they help you. Otherwise they'll just spend hours telling you why you're wrong and what you're looking for is completely unnecessary, never mind the fact that you told them why *you* would want it. +1 for a good question though. – user541686 Jan 16 '14 at 12:11
  • I'd wonder why you're copy-pasting in the first place, but maybe I'm approaching this on too high of a level. – rubenvb Dec 19 '14 at 12:30
  • @rubenvb It was a problem which occurred in a graph framework, where most of the edge / vertex classes were quite similar, with subtle differences. The implementations themselves were very small, just a few lines of code, so there was not much to be done in terms of using a common implementation, be it a base class or a utility function. So unfortunately stuff got copy/pasted around. Also see http://stackoverflow.com/questions/21143835/can-i-implement-an-autonomous-self-member-type-in-c – the swine Dec 19 '14 at 16:49

3 Answers3

9

The problem is that C++ is lacking a self keyword.

I typically write:

struct Foo
{
   typedef Foo self;

   static void bar()
   {
      self* ptr = nullptr;
   }
};

I realise you still have to make sure the typedef is correct, but at least this way you can have it at the top of the type definition where you'll notice it.

With hackery, though, you can make this entirely autonomous.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Too bad about the decltype, that would have been the coolest (thanks a lot for trying). But I'm still being comforted by hearing someone say "I typically write", I was a bit worried that I'm trying to achieve stupid things. – the swine Jan 15 '14 at 17:08
  • You didn't really think that an expression using `this` (even one that isn't evaluated) would work in a static function, did you? – James Kanze Jan 15 '14 at 17:34
  • @JamesKanze: No but I thought I might as well give it a go, just in case it got special treatment inside an unevaluated context, or something. Stranger things have happened. (BTW it was at class scope, not in a static member function.) – Lightness Races in Orbit Jan 15 '14 at 17:35
  • I think `this_type` and `base_type` goes well with the C++ naming conventions, and Boost also follows this convention. – user541686 Jan 16 '14 at 12:16
3

C++ does not have any feature to get the name of the current class, namespace, etc. In C++11 you can get type of the variable, but you need the variable in the first place. In this case you do not have anything to start with.

Kirill Kobelev
  • 10,252
  • 6
  • 30
  • 51
3

I like the idea of trying to introduce some general name that you can refer to in unrelated classes; for maintainability.

My first approach would be a simple one: Provide a typedef in the enclosing class. Give the typedef the same name in every unrelated class.

class Impossible {
public:
    typedef Impossible Enclosing;
    static void Fun()
    {   
        Enclosing* theObject = 0;
    }   
};

Doing this will also have the effect -- and I would call it a benefit -- of failing to compile in new unrelated classes where you haven't provided the typedef.

John Dibling
  • 99,718
  • 31
  • 186
  • 324