Можно ли использовать аргумент шаблона в качестве строки? - PullRequest
1 голос
/ 12 октября 2011

Я хочу использовать переданный параметр шаблона в качестве строки.Возможно ли это?

T это класс, что мне нужно изменить, чтобы этот код работал?

void registerClass(const std::string &name, Handler *handler);

template<class T>
void registerClass() {
   registerClass( "get T as string", new DefaultHandler<T>());
}

Ответы [ 4 ]

6 голосов
/ 12 октября 2011

Ближайший, который вы можете получить, чтобы получить тип в виде строки, - typeid( T )->name().Однако стандартизации для имен типов не существует, поэтому вы не можете доверять получению действительного имени из него.Стандартная совместимая реализация может очень хорошо возвращать пустые строки для всех имен типов.

2 голосов
/ 13 октября 2011

Это должен быть параметр шаблона?Может быть, процессор C может помочь:

void registerClass(const std::string &name, Handler *handler);

#define REGISTER_CLASS(t) (registerClass( #t, new DefaultHandler<t>()))

void RegisterMyClasses() {  
  REGISTER_CLASS(int);
  REGISTER_CLASS(Foo);
}
2 голосов
/ 12 октября 2011

Вы можете использовать typeid(T) для получения структуры std::type_info для описания типа.Эта структура, в свою очередь, имеет члена name(), который должен дать вам имя.

template<class T>
void fooClass() {
   foo( "get " + std::string( typeid(T).name() ) +" as string", new DefaultHandler<T>());
}
1 голос
/ 13 октября 2011

C ++ не имеет отражения , как в C # или Java. Это не ошибка. Отражение было рассмотрено более одного раза и намеренно исключено из языка.

ОДНАКО , вы можете получить что-то близкое к вашему дизайну. Вы должны будете сделать много работы самостоятельно. По сути, вам придется реализовать рефлексию на языке, который намеренно не обеспечивает его.

Ваш текущий дизайн близок. Если бы я реализовал рефлексию так, как вы, кажется, идете, я бы сделал:

class Reflection_registry {
    std::map<std::string, Handler*> registry_;

public:
    void registerClass(const std::string& name, Handler* handler) {
        registry_[name] = handler;
    }

    Handler* getHandlerForClass(std::string& name) {
        std::map<std::string, Handler*>::iterator itor = registry_.find(name);
        return itor == registry_.end() ? NULL : itor->second;
    }
}

Дело в том, что вы несете ответственность за то, чтобы придумать соответствующие имена, от руки , и поддерживать их в актуальном состоянии. Как и предполагали другие, вы можете использовать typeid и std::type_info s для генерации имен - это в значительной степени то, для чего std::type_info был разработан.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...