I am writing several template classes for parsing some text data files, and, like most of them, most parsing errors will be due to errors in the data file, which are mostly not written by programmers, and therefore I need a good message about why the application failed to load, for example something like:
Error analysis in the .txt example. The value ("notaninteger") of the [MySectiom] key is not a valid int value
I can process files, sections, and key names from the arguments passed to the template function and member classes in the class, however I'm not sure how to get the name of the type that the template function is trying to convert to.
My current code looks, with specializations for simple strings, etc.
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);}
An identifier probably should not do specific overloads for each type that data files can use, since there are many of them ...
I also need a solution that does not incur any overhead at runtime unless an exception occurs, i.e. a fully compiled workaround is what I want, as this code is called tons of times, and the load time is already slightly longer.
EDIT: Ok, this is the solution I came across:
I have .h types containing the following
#pragma once template<typename T> const wchar_t *GetTypeName(); #define DEFINE_TYPE_NAME(type, name) \ template<>const wchar_t *GetTypeName<type>(){return name;}
Then I can use the DEFINE_TYPE_NAME macro in cpp files for each type that I need to deal with (for example, in a cpp file that defines the type to start).
The linker can then find a suitable template specialization if it is defined somewhere, or throw a linker error otherwise so that I can add this type.