Тип замкнутого класса С++ в статической функции-члене

Я предполагаю, что это совершенно невозможно, но что, если. Возможно ли каким-то образом получить тип охватывающего класса в статической функции-члене в любой версии С++?

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

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

Есть ли способ получить тип охватывающего класса (Impossible в этом случае) без написания имени класса в функции?

Причина, по которой я хотел бы сделать это, - это не повторять имя класса в функции. Это может легко привести к сложному обнаружению ошибки копирования-вставки, если произошло что-то вроде этого:

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 ...
    }
}

Есть ли хороший способ предотвратить такое явление? Я мог представить, что касался чего-то, что было объявлено частным в окружающем классе, но это заставило бы меня писать дополнительный код (поскольку мой текущий проект не содержит каких-либо неотъемлемых частных членов, все является общедоступным).

Ответ 1

Проблема в том, что в С++ отсутствует ключевое слово self.

Я обычно пишу:

struct Foo
{
   typedef Foo self;

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

Я понимаю, что вам все равно нужно убедиться, что typedef верен, но по крайней мере таким образом вы можете получить его в верхней части определения типа, где вы его заметите.

С хакером, тем не менее, вы можете сделать это полностью автономным.

Ответ 2

У С++ нет никакой функции для получения имени текущего класса, пространства имен и т.д. В С++ 11 вы можете получить тип переменной, но вам нужна переменная в первую очередь. В этом случае вам не с чем начать.

Ответ 3

Мне нравится идея попытаться ввести какое-то общее имя, на которое вы можете ссылаться в несвязанных классах; для ремонтопригодности.

Мой первый подход был бы простым: укажите typedef в охватывающем классе. Дайте typedef одно и то же имя в каждом несвязанном классе.

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

Выполнение этого также будет иметь эффект - и я бы назвал его полезным - из-за невозможности компиляции в новых несвязанных классах, где вы не предоставили typedef.