Я пытаюсь расширить свои навыки программирования шаблонов и столкнулся с проблемой, для которой я не вижу правильного решения.Это упражнение для личного обучения только для более сложных шаблонов.
Эта цель: написать шаблон для преобразования любого целочисленного типа (используя sprintf или swprintf) в строку или строку в зависимости от типа формата.sring.Нет необходимости в проверке ошибок (пока что).
Проблема в том, что формат указан как (const char*) NULL
или (const wchar_t*) NULL
Мне нужно указать значение по умолчанию LITERALлибо "%i"
, либо L"%i"
, для этого мне нужно определить тип символа переменной формата.Я использую функции для этого сейчас, используя SFINAE.Однако я хотел бы использовать переменную для этого, но я не думаю, что SFINAY работает с переменными (или я ошибаюсь).
Вот мой (рабочий) код на данный момент:
////////////////////////////////////////////////////////////////////////////////
template < typename T ,typename I >
inline
typename std::enable_if< std::is_same< T ,char >::value ,int >::type
str_printf ( T* szBuff ,int iLen ,const T* szFrmt ,I iNum )
{ return sprintf_s( szBuff ,iLen ,szFrmt ,iNum ); }
template < typename T ,typename I >
inline
typename std::enable_if< std::is_same< T ,wchar_t >::value ,int >::type
str_printf ( T* szBuff ,int iLen ,const T* szFrmt ,I iNum )
{ return swprintf_s( szBuff ,iLen ,szFrmt ,iNum ); }
////////////////////////////////////////////////////////////////////////////////
template < typename T >
inline
typename std::enable_if< std::is_same< T ,char >::value ,const char* >::type
Dflt_Frmt () { return "%i"; }
template < typename T >
inline
typename std::enable_if< std::is_same< T ,wchar_t >::value ,const wchar_t* >::type
Dflt_Frmt () { return L"%i"; }
////////////////////////////////////////////////////////////////////////////////
template < typename T ,typename I >
inline
std::basic_string< T ,std::char_traits < T > >
to_string ( I iNum ,const T* pszFrmt )
{
const int iLen (65);
T szBuff [iLen] = {0};
std::basic_string< T ,std::char_traits < T > > frmt ((pszFrmt && (*pszFrmt)) ? pszFrmt : Dflt_Frmt<T>() );
str_printf( szBuff ,iLen ,frmt.c_str() ,iNum );
return szBuff;
}
////////////////////////////////////////////////////////////////////////////////
это то, что я хотел бы сделать (очевидно, это не работает)
////////////////////////////////////////////////////////////////////////////////
template < typename T ,typename I >
inline
std::basic_string< T ,std::char_traits < T > >
to_string ( I iNum ,const T* pszFrmt )
{
const int iLen (65);
T szBuff [iLen] = {0};
// declare a Variable of const T* and initialie it with "%i" or L"%i"
typename std::enable_if< std::is_same< T ,char >::value ,const char* >::type dft("%i");
typename std::enable_if< std::is_same< T ,wchar_t >::value ,const wchar_t* >::type dft (L"%i");
// doesn't work (error : type is not a member of std::enable_if< ... > !
std::basic_string< T ,std::char_traits < T > > frmt ((pszFrmt && (*pszFrmt)) ? pszFrmt : dft );
str_printf( szBuff ,iLen ,frmt.c_str() ,iNum );
return szBuff;
}
////////////////////////////////////////////////////////////////////////////////
Могу ли я сделать это аналогичным образом или рабочая версия - лучший?Или как это сделать>
Мне не нужно предлагать использовать строковые потоки (вопрос не в этом).
Использование MSVS 2010 (и извините, без повышения).
Спасибо.