Вопрос
Каков правильный способ иметь помощники по шаблонам и дополнительные специализированные перегрузки в отдельных файлах, чтобы включения не зависели от порядка?
Есть ли правильный способ сделать что-то в ситуациях, подобных моей (см. описание ниже)?
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: я не уверен, что описание составлено правильно. Пожалуйста, не стесняйтесь помочь сформулировать это лучше.
Описание
Код, с которым я работаю, основан на использовании std::vector
из boost::variant
для хранения атрибутов некоторых примитивов. Пример:
BOOST_STRONG_TYPEDEF(std::string, PointName)
BOOST_STRONG_TYPEDEF(double, CoordinateX)
BOOST_STRONG_TYPEDEF(double, CoordinateY)
typedef boost::variant<PointName, CoordinateX, CoordinateY> PointAttribute;
typedef std::vector<PointAttribute> PointAttributes;
BOOST_STRONG_TYPEDEF(std::string, LineName)
BOOST_STRONG_TYPEDEF(double, LineLength)
typedef boost::variant<LineName, LineLength> LineAttribute;
typedef std::vector<LineAttribute> LineAttributes;
Я пишу помощник для добавления новых атрибутов, содержащихся в заголовочном файле VariantHelper.h
:
template <typename TValue, typename TVariant, typename TAllocator>
inline void Add(
std::vector<TVariant, TAllocator>& attributes,
const TValue& value)
{
attributes.push_back(TVariant(value));
}
template <typename TVariant, typename TValue, typename TAllocator>
inline std::vector<TVariant, TAllocator>& operator<<(
std::vector<TVariant, TAllocator>& attributes,
const TValue& value)
{
Add(attributes, value);
return attributes;
}
Я хотел бы расширить этот помощник для класса PointXY
в отдельном заголовочном файле PointVariantHelper.h
:
// forward declaration
template <typename TValue, typename TVariant, typename TAllocator>
inline void Add(
std::vector<TVariant, TAllocator>& attributes,
const TValue& value);
template <typename TVariant, typename TAllocator>
inline void Add(
std::vector<TVariant, TAllocator>& attributes,
const PointXY& pnt)
{
Add(attributes, CoordinateX(pnt.X()));
Add(attributes, CoordinateY(pnt.Y()));
}
Чтобы использовать помощник для PointXY
, мне нужно:
#include "PointVariantHelper.h"
#include "VariantHelper.h"
Проблемы
- Порядок включения заголовка не может быть изменен
- Выполнение форвардных объявлений кажется обходным путем (в противном случае
Add
не разрешится должным образом). Аналогичная проблема описана в этом вопросе SO: «Поиск имени для перегруженных функций, определенных позже < /а>».
Цели
- Вариантные хелперы и специализированные хелперы должны быть разделены, и пользователь должен включать хелперы только для необходимых классов.