Как получить имя класса?

Если я определил класс:

class Blah {};

Как я могу:

std::string const className = /* What do I need to do here? */;
assert( className == "Blah" );

Я не думаю, что typeid(). name() - хорошая идея, так как это реализация компилятора. Есть ли что-либо, предоставляемое стандартом С++ или Boost?

Примечание. Если класс был унаследован от Qt QObject, я мог бы легко использовать QMetaObject::className() для получения имени класса.

6 ответов

Вот так:

class Blah { static std::string const className() { return "Blah"; }};
std::string const name = Blah::className();
assert(name == "Blah");

Или это:

class Blah {};
template < typename T > struct name;
template < > struct name<blah> { static std::string value() { return "Blah"; }};
std::string const classname = name<blah>::value();
assert(classname == "Blah");
</blah></blah>

навороченные:

#define DECLARE_NAMED_CLASS( Name ) \
struct Name;\
template < > struct name<name> { static std::string value() { return #Name; }};\
struct Name
DECLARE_NAMED_CLASS(Blah) {};
std::string const className = name<blah>::value();
...
</blah></name>

Или это:

class Blah : QObject { Q_OBJECT };

Или это:... Или это:...


Тестирование класса, рассматривая его имя, звучит ужасно, как подход Java-стиля ко мне, и на С++ вы должны быть осторожны при попытке применить одни и те же шаблоны! Лучшим способом было бы использовать что-то вроде boost::type_traits и может быть is_same с именем реального класса.


Я не думаю, что typeid(). name() - хорошая идея, поскольку он компилятор конкретная реализация.

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

Есть ли что-либо, предоставляемое стандартом С++ или Boost?

Нет стандартных средств, которые возвратили бы имя класса в некоторой канонической форме.


Метод QObject- > metaObject() действителен для Qt, за исключением классов на основе QGraphicsItem, которые не наследуются от QObject...


Я не думаю, что существует какое-либо решение, не относящееся к компилятору, к такой проблеме, которая не включает много макросов в объявлении класса (на самом деле, если я правильно понял документацию QT, строка, которую вы получаете с objectName, действительно назначена "вручную", я думаю, с кодом, созданным moc).

С другой стороны, в общем случае, чтобы проверить, не является ли класс объекта одним из них, вы не хотите, чтобы вы не выполняли сравнение строк, а вместо этого проводили сравнение типов.

assert(typeid(YourObject)==typeid(Blah));

Но, возможно, вам лучше объяснить, чего вы пытаетесь достичь.


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

licensed under cc by-sa 3.0 with attribution.