Я пишу кілька класів шаблонів для синтаксичного аналізу деяких текстових файлів даних, і, як такий, переважно більшість помилок синтаксичного аналізу будуть пов'язані з помилками у файлі даних, які здебільшого не написані програмістами, і тому вони потребують гарне повідомлення про те, чому програму не вдалося завантажити, наприклад щось на зразок:
Помилка синтаксичного аналізу example.txt. Значення ("notaninteger") ключа [MySectiom] не є дійсним int
Я можу опрацювати імена файлів, розділів та ключів з аргументів, переданих функції шаблону та змінних членів у класі, однак я не впевнений, як отримати ім'я типу, який намагається перетворити функція шаблону.
Мій поточний код виглядає так, що спеціалізується на простих рядках і таких:
template<typename T> T GetValue(const std::wstring §ion, const std::wstring &key)
{
std::map<std::wstring, std::wstring>::iterator it = map[section].find(key);
if(it == map[section].end())
throw ItemDoesNotExist(file, section, key)
else
{
try{return boost::lexical_cast<T>(it->second);}
//needs to get the name from T somehow
catch(...)throw ParseError(file, section, key, it->second, TypeName(T));
}
}
Мені, скоріше, не доведеться робити конкретні перевантаження для кожного типу, який можуть використовувати файли даних, оскільки їх багато ...
Крім того, мені потрібне рішення, яке не спричиняє жодних накладних витрат на виконання, якщо не виникає виняток, тобто саме те, що я хочу, це рішення часу компіляції, оскільки цей код називається тоннами разів, а час завантаження вже стає дещо довшим.
EDIT: Добре, це рішення, яке я придумав:
У мене є type.h, що стосується наступного
#pragma once
template<typename T> const wchar_t *GetTypeName();
#define DEFINE_TYPE_NAME(type, name) \
template<>const wchar_t *GetTypeName<type>(){return name;}
Тоді я можу використовувати макрос DEFINE_TYPE_NAME для створення файлів cpp для кожного типу, з яким мені потрібно мати справу (наприклад, у файлі cpp, який визначив тип для початку).
Потім компонувальник зможе знайти відповідну спеціалізацію шаблону до тих пір, поки вона була десь визначена, або викинути помилку посилання в іншому випадку, щоб я міг додати тип.