Получить шаблонный тип в виде строки - PullRequest
2 голосов
/ 04 декабря 2009

После прочтения хеширования строки времени компиляции C ++ с Boost.MPL и рассмотрения возникшей проблемы мне пришло в голову следующее:

У меня есть базовый класс:

template<class Command>
class Base {
  typedef Command CommandType;
}

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

class CommandInstantiatorA : public Base<CommandA>
{
public:
   static std::string GetID() { return "CommandInstantiatorA "; }
}

Однако есть еще один метод (GetID), который я не смог «шаблонизировать», который возвращает уникальный идентификатор через приложение. Я хотел бы иметь возможность хэшировать тип, передаваемый классу Base, поэтому другим классам нужно будет только указать тип. Примерно так:

template <class Base>
class Base {
   typedef boost::hash_value(TO_STRING(Base)) ID; //should also be read as: typedef boost::hash_value("CommandA") ID;
   ...
}

Существует ли такой макрос (TO_STRING), который бы вывел результат "CommandA" в последнем примере. Есть ли в Boost.MPL что-нибудь, что может это сделать?

Ответы [ 3 ]

7 голосов
/ 04 декабря 2009

Не в ускорении, но это только часть C ++, поэтому я надеюсь, что это подойдет - возможно, вы могли бы подумать об использовании RTTI - например, вот так http://en.wikipedia.org/wiki/Typeid

int main () {
Person person;
Employee employee;
Person *ptr = &employee;
// The string returned by typeid::name is implementation-defined
std::cout << typeid(person).name() << std::endl;   // Person (statically known at compile-time)
std::cout << typeid(employee).name() << std::endl; // Employee (statically known at compile-time)
std::cout << typeid(ptr).name() << std::endl;      // Person * (statically known at compile-time)
std::cout << typeid(*ptr).name() << std::endl;     // Employee (looked up dynamically at run-time
                                                   //           because it is the dereference of a
                                                  //           pointer to a  polymorphic class)
}
1 голос
/ 04 декабря 2009

Вы можете использовать строковое преобразование препроцессора - это, вероятно, не решает все проблемы, но вы можете получить строку:

#include <iostream>
using namespace std;

#define ToString(x) #x
struct C { static const string id; };

const string C::id = ToString(C_ID);

int main()
{
    C c;
    cout << c.id << endl;
}

Печать:

C_ID
0 голосов
/ 04 декабря 2009

Препроцессор (то есть макросы) имеет строковый оператор, который может заключить любой токен в двойные кавычки. Это не может делать то, что вы хотите, по крайней мере, так, как написано, потому что оно будет преобразовывать в строку буквальный токен "Base", а не подставленный параметр шаблона.

...