Так как количество параметров, вставляемых в строку формата, не может быть проверено компилятором, невозможно сделать это действительно безопасным для типов во время компиляции.
Вы можете получить большую часть пути, просто имея несколько перегрузок для различного числа вставленных параметров, а затем указав вставленные значения с помощью чего-то гибкого, например boost::any
. Таким образом, перегрузка для двух параметров будет:
std::string FormatMessage(HINSTANCE hinst, DWORD id, const boost::any &arg1, const boost::any &arg2);
Когда вы извлекаете значение из arg1
, boost выдаст, если вы попытаетесь получить неправильный тип, поэтому вам просто нужно изучить строку формата и попытаться получить требуемый тип из каждого аргумента.
В качестве альтернативы вы можете использовать шаблоны и std :: ostringstream (или boost :: lexical_cast) для очень гибкой версии; снова будут перегрузки, позволяющие варьировать число аргументов, поэтому вот версия с одним аргументом:
template <class TArg1>
std::string FormatMessage(HINSTANCE hinst, DWORD id, const TArg1 &arg1)
{
std::ostringstream arg1Stream;
arg1Stream << arg1;
std::string arg1String = arg1Stream.str();
DWORD_PTR argArray = reinterpret_cast<DWORD_PTR>(arg1String.c_str());
// ... etc
}
Таким образом, вы можете получить строку из каждого аргумента, если передаваемый тип может быть передан в потоковом режиме, и больше ничего не требуется, если строки формата ожидают вставки только строк.