Есть шаблонная функция, одна из перегрузок которой определена для простых типов — куда входит определенное фиксированное множество, скажем
int,unsigned int,char,unsigned char,short,unsigned short,long,unsigned long,foat,double и любые указатели.
Для всех числовых типов необходимо внутри функции получить некий константный индекс, однозначно соответствующий типу T.
Для указателей пускай будет один индекс на всех (ну или никакого — то есть -1 или что-то такое).
Вопрос — как это сделать? Возможно как-то через boost::mpl, но как?
XC>Для всех числовых типов необходимо внутри функции получить некий константный индекс, однозначно соответствующий типу T. XC>Для указателей пускай будет один индекс на всех (ну или никакого — то есть -1 или что-то такое).
Не уверен, что нужен boost, всё и так просто и прозрачно:
#include <iostream>
#include <type_traits>
int GetId()
{
static int id = 0;
id++;
return id;
}
template <class T>
struct TypeId
{
typedef T type;
static const int id;
};
template <class T>
struct TypeId<T*>
{
typedef T* type;
static const int id = -1;
};
//static template <class T>
const int TypeId<T>::id = GetId();
class A
{
};
class B
{
};
class C
{
public:
C()
{
std::cout << "id of this for C = " << TypeId<std::remove_pointer<decltype(this)>::type>::id << std::endl;
}
};
template<class T>
void foo(T & val)
{
std::cout << "foo, id of T = " << TypeId<T>::id << std::endl;
}
int main(int argc, char* argv[])
{
int n = 0;
foo(n);
int* pn = &n;
foo(pn);
char ch = 'a';
foo(ch);
char* pch = &ch;
foo(pch);
std::cout << "id of A = " << TypeId<A>::id << std::endl;
std::cout << "id of C = " << TypeId<C>::id << std::endl;
std::cout << "id of A = " << TypeId<A>::id << std::endl;
std::cout << "id of B = " << TypeId<B>::id << std::endl;
std::cout << "id of C = " << TypeId<C>::id << std::endl;
std::cout << "id of int = " << TypeId<int>::id << std::endl;
std::cout << "id of int* = " << TypeId<int*>::id << std::endl;
std::cout << "id of A* = " << TypeId<A*>::id << std::endl;
return 0;
}
Здравствуйте, x-code, Вы писали:
XC>скажем XC>int,unsigned int,char,unsigned char,short,unsigned short,long,unsigned long,foat,double и любые указатели. XC>Для указателей пускай будет один индекс на всех (ну или никакого — то есть -1 или что-то такое).
Ну можно переписать все простые типы вручную.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, ajanov, Вы писали:
A>hash_code() не будет выдавать последовательных индексов,
Не было в требованиях. Индекс — может быть индексом в мапе, например. A>а также может возвращать одинаковые значения для двух разных типов
Только то, что касается cv.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Здравствуйте, Ops, Вы писали:
A>>а также может возвращать одинаковые значения для двух разных типов Ops>Только то, что касается cv.
Конечно не только. Там используются алгоритмы не сложнее MurmurHash2. Коллизий — тьма. Вот пример подобрал: http://ideone.com/GL7Ngk
Конечно, для ограниченного множества типов можно проверить, что hash_code попарно не совпадают (например у типов signed и unsigned ), и если это так, то использовать этот метод. Но что программа должна будет делать, hash_code внезапно начнут совпадать? Использовать другой метод? Тогда лучше на него сразу и переключится.
Здравствуйте, watchmaker, Вы писали:
W>Конечно не только. Там используются алгоритмы не сложнее MurmurHash2. Коллизий — тьма. Вот пример подобрал: http://ideone.com/GL7Ngk
У меня под рукой только какой-то драфт, судя по нему, это несоответствие стандарту (18.7.1-8):
Remark: an implementation should return different values for two type_info objects which do not compare equal.
W>Конечно, для ограниченного множества типов можно проверить, что hash_code попарно не совпадают (например у типов signed и unsigned ), и если это так, то использовать этот метод. Но что программа должна будет делать, hash_code внезапно начнут совпадать? Использовать другой метод? Тогда лучше на него сразу и переключится.
Ну печально это.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Здравствуйте, watchmaker, Вы писали:
W>Конечно не только. Там используются алгоритмы не сложнее MurmurHash2. Коллизий — тьма. Вот пример подобрал: http://ideone.com/GL7Ngk
тут дело не в алгоритме хеширования. 26^10 > 2^32. в целом, если у тебя 10+ тыщ типов, то вероятность коллизии будет достаточно велика
BZ>тут дело не в алгоритме хеширования. 26^10 > 2^32.
Это да. Я криво написал. Не столь важно, какой конкретно из алгоритмов используется (MurmurHash или FNV-1a), а то что для этого используется независимое хеширование, а не альтернативный подход вроде этого
.
BZ>в целом, если у тебя 10+ тыщ типов, то вероятность коллизии будет достаточно велика
А могли бы и link-time PHF реализовать. Отсрочив появление коллизий на куда как более далёкие времена.
Здравствуйте, watchmaker, Вы писали:
W>Здравствуйте, Ops, Вы писали:
Ops>>У меня под рукой только какой-то драфт, судя по нему, это несоответствие стандарту (18.7.1-8): Ops>>
Ops>>Remark: an implementation should return different values for two type_info objects which do not compare equal.
W>should != must.
разве? разве не все стандарты пишутся через should (вежливое предписание)?
Здравствуйте, _hum_, Вы писали:
__>Ops, а может, в знаете, в чем принцпипиальная трудность в языке ввести числовую идентификацию встроенных типов? зачем эти извращения с typeid-ами?
Принцип раздельной компиляции мешает определять id типов до загрузки всех модулей...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, _hum_, Вы писали:
__>>Ops, а может, в знаете, в чем принцпипиальная трудность в языке ввести числовую идентификацию встроенных типов? зачем эти извращения с typeid-ами?
E>Принцип раздельной компиляции мешает определять id типов до загрузки всех модулей...
Erop, я вас, по традиции, с первого раза не могу понять. я имел в виду, что мешает в стандарт ввести, что идентификатор uint8 — 0, uint16 — 1, float — 2 и т.п. и организовать compile-time type_trait<type>::uid?
Здравствуйте, _hum_, Вы писали:
E>>Принцип раздельной компиляции мешает определять id типов до загрузки всех модулей...
__>Erop, я вас, по традиции, с первого раза не могу понять. я имел в виду, что мешает в стандарт ввести, что идентификатор uint8 — 0, uint16 — 1, float — 2 и т.п. и организовать compile-time type_trait<type>::uid?
А с std::vector<float> что делать?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском