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