Уникальный числовой идентификатор для шаблонного класса, использующего адрес функции - PullRequest
0 голосов
/ 01 февраля 2010

Итак, этот вопрос задавался ранее, но я хотел задать вопрос с некоторыми из этих ключевых слов в названии.

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

То есть способ дифференциации:

foo<int> f1;
foo<char> f2;
classID(f1) != classID(f2);

но

foo<int> f3;
foo<int> f4;
classID(f3) == classID(f4);

Относится к:

в C ++, как использовать одиночный код, чтобы каждый класс имел уникальный интегральный идентификатор?

Присвоение уникальных числовых идентификаторов экземплярам шаблонного класса

Ответы [ 2 ]

3 голосов
/ 01 февраля 2010
template<class T>
class Base
{
public:
    static void classID(){}
private:
    T* t;
};

int main()
{
    Base<int> foo;
    Base<int> foo2;
    Base<char> foo3;

    /*
    unsigned int i  = reinterpret_cast<unsigned int>(Base<int>::classID);
    unsigned int ii = reinterpret_cast<unsigned int>(Base<char>::classID);
    unsigned int iii = reinterpret_cast<unsigned int>(Base<int>::classID);
    /*/
    unsigned int i  = reinterpret_cast<unsigned int>(foo.classID);
    unsigned int ii  = reinterpret_cast<unsigned int>(foo2.classID);
    unsigned int iii  = reinterpret_cast<unsigned int>(foo3.classID);
    //*/

    return ((i != ii) + (i <= ii) + (i >= ii)) == 2;
}

Вот как! Это легкий, супер легкий и не использует RTTI, хотя он использует невероятно небезопасный reinterpret_cast

Хотя, может, я что-то упустил?

1 голос
/ 01 февраля 2010

Я думаю, что вы можете просто использовать статическую функцию для этого и наследовать ее класс:

struct IdCounter { static int counter; };
int IdCounter::counter;

template<typename Derived>
struct Id : IdCounter {
  static int classId() {
    static int id = counter++;
    return id;
  }
};

struct One : Id<One> { };
struct Two : Id<Two> { };

int main() { assert(One::classId() != Two::classId()); }

Конечно, это не будет статической константой времени компиляции - я не думаю, что это возможно автоматически (вам нужно было бы добавить эти типы вручную в некоторый список типов, например mpl::vector). Обратите внимание, что для простого сравнения типов на равенство вам не нужно все это. Вам просто нужно использовать is_same (находится в boost и других библиотеках и тривиально писать), что дает постоянную времени компиляции

template<typename A, typename B>
struct is_same { static bool const value = false; };
template<typename A> 
struct is_same<A, A> { static bool const value = true; };

int main() { char not_true[!is_same<One, Two>::value ? 1 : -1]; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...