В последнее время я начал работать над внедрением системы баз данных на основе графов. Однако я столкнулся с небольшой проблемой.
Вершины в графе могут содержать свойства любого типа сопоставимого типа. Я думал о создании карты для них, так как ключи всегда основаны на строках. Тем не менее, я не хочу беспокоиться о фактическом типе, единственное, что я хочу сделать, это сравнить их и по-прежнему проводить проверки безопасности. Как бы мне это сделать?
Когда я впервые подошел, я подумал об использовании boost, однако он все равно доставит мне головную боль при выполнении некоторой ручной проверки типов, что я абсолютно не хочу делать.
В Java я бы сделал что-то подобное, однако я не использую подобные вещи в C ++.
map<String, ? extends comparable>
Причина этого в том, что свойство может быть буквально любого сопоставимого типа.
Не фактический ответ, а запрошенный пример:
Я привык создавать такие шаблоны:
SomeClass.h:
#guards etc
template<class T> //or whatever you need
class SomeClass {
public:
SomeClass();
T content();
private:
T m_content;
}
SomeClass.cpp:
#include "SomeClass.h"
template<class T>
SomeClass::SomeClass(){
m_content = (T) 0;
}
template<class T>
T SomeClass::content(){
return T;
}
#include "SomeClass_Specializations.h"
SomeClass_Specializations.h:
#guards etc
#include "SomeClass.h"
#include "MyMagicUint.h"
//only types that behave like unsigned int may be added!
template class SomeClass<unsigned short>;
template class SomeClass<unsigned int>;
template class SomeClass<unsigned long>;
template class SomeClass<MyMagicUint>;
Если вы сделаете это таким образом, вы можете специализировать длинный список некоторых распространенных сопоставимых типов и написать комментарий, в котором вы опишите, что другим людям разрешено добавлять в этот список (в моем примере типы unsigned int like по некоторым причинам).
В результате будут работать только те, которые специализируются здесь (поскольку в противном случае реализация отсутствует), вы, вероятно, рассмотрели большинство из них, и в тех редких случаях, когда кому-то нужна другая специализация, он просто добавляет ее в список.
В конце концов, выполнение настолько строго, насколько это может быть необязательно, так как оно не будет компилироваться в любом случае, если будет выполнено какое-либо запрещенное действие, например использование <-оператор, когда он не определен для этого типа, но если вы хотите такой строгий контроль, вы можете сделать это так. Конечно, это не имеет динамического контроля? расширяется …, но у него есть контроль по крайней мере. Еще одним преимуществом является то, что вы можете реализовать код в файле CPP как обычно, вместо того, чтобы помещать все в заголовок, как требуется для динамического шаблона, поэтому в основном это мой стандарт.
Конечно, вы могли бы просто написать содержимое файла специализации прямо в нижней части CPP вместо того, чтобы включать другой заголовок, но я думаю, что заголовок специализации более элегантен, информируя потенциальных пользователей о том, что разрешено, и давая им возможность добавить в это, не глядя на реализацию.
Других решений пока нет …