Почему следующий код является уникальным typeID ?!
using TypeId = uintptr_t;
template < typename T >
static TypeId GetTypeId()
{
static uint32_t placeHolder;
return (reinterpret_cast<TypeId>(&placeHolder));
}
Я не понимаю, почему это не просто случайная ячейка памяти, а своего рода «неправильное использование» … Спасибо за ответы заранее.
Вы правы в том, что реализация злоупотребляет «случайная ячейка памяти» из области видимости статический переменная, но это не означает, что гарантия, о которой вы говорите, не действует: GetTypeId<T>
будет уникальным для каждого экземпляра этого.
Заметка: Однако следует помнить о том, что
uintptr_t
является не гарантированно будет доступно для каждой платформы. Полностью переносимый способ реализации функции — вернутьvoid*
, который гарантированно сможет хранить каждый адрес каждого объекта в программе.
В C ++ есть гарантия, что каждый объект должен находиться по уникальному адресу, если мы не говорим об объекте, который является субобъектом, если другой. В таком случае они могут иметь один и тот же адрес (и в случаях, когда требуется совместное использование адреса, как в случае классов стандартной компоновки и их первого члена-данных).
1.8p6
Объектная модель C ++[intro.object]
Если объект не является битовым полем или подобъектом базового класса нулевого размера, адрес этого объекта является адресом первого байта, который он занимает. Два объекта, которые не являются битовыми полями, могут иметь один и тот же адрес, если один является подобъектом другого, или если хотя бы один является подобъектом базового класса нулевого размера, и они имеют разные типы; иначе, они должны иметь разные адреса.
У нас также есть явное предложение о том, что каждая специализация шаблона-функции, которая включает в себя статический переменная имеет собственную уникальную копию указанной статической переменной:
14.8p2
Специализация шаблона функции[temp.fct.spec]
Каждая специализация шаблона функции, созданная из шаблона, имеет свою собственную копию любой статической переменной.
Так как переменная, которая объявлена статический уникален для каждого экземпляра GetTypeId<T>
, где T
произвольный тип, каждый объект с именем placeHolder
В этом шаблоне специализация обязана уникальному объекту.
Это должен быть уникальный объект, и с этим; у него должен быть отдельный адрес.
Примечание 1) В C ++ 11 у нас есть
std::type_index
который выполняет гарантию вы после.
Заметка 2) C ++ 11 стандартная тяга n3337 был использован в качестве ссылки в этом посте.