В настоящее время я переношу кучу кода, который ранее был скомпилирован только с помощью Visual Studio 2008. В этом коде есть такое расположение:
template <typename T>
T convert( const char * s )
{
// slow catch-all
std::istringstream is( s );
T ret;
is >> ret;
return ret;
}
template <typename T, typename T2>
T convert( T2 * s )
{
return convert<T>( static_cast<const char*>( s ));
}
template <typename T, typename T2>
T convert( T2 s )
{
return T( s );
}
template <>
inline int convert<int>( const char * s )
{
return (int)atoi( s );
}
Как правило, существует множество специализаций шаблонной функции с различными типами возвращаемого значения, которые вызываются следующим образом:
int i = convert<int>( szInt );
Проблема в том, что эти специализации шаблонов приводят к "неоднозначной специализации шаблона". Если бы эти специализации функций отличались чем-то другим, кроме типа возвращаемого значения, я, очевидно, мог бы просто использовать перегрузки, но это не выход.
Как мне решить эту проблему, не меняя все места, где вызываются функции преобразования?
Обновление Я добавил эти две универсальные специализации шаблонов, которые я пропустил в первый раз. Мне стыдно сказать, я не уверен в мотивации второго, но первый связан с тем, что функция convert используется во многих местах, где строковые данные передаются как void *. Я не могу проверить это с помощью GCC прямо сейчас, но я подозреваю, что это может быть проблемой.
Обновление 2 Вот полный файл cpp, который будет воспроизводить это. Если вы удалите обе функции «общего назначения», он скомпилируется. Если вы оставите любой из них, возникнет ошибка неоднозначной специализации шаблона.
#include <iostream>
#include <sstream>
template <typename T>
T convert( const char * s )
{
// this is a slow slow general purpose catch all, if no specialization is provided
std::istringstream is( s );
T ret;
is >> ret;
return ret;
}
// general purpose 1
template <typename T, typename T2>
T convert( T2 * s )
{
return convert<T>( static_cast<const char*>( s ));
}
// general purpose 2
template <typename T, typename T2>
T convert( T2 s )
{
return T( s );
}
// Type specialized
template <>
inline float convert<float>( const char * s )
{
return (float)atof( s );
}
int main( int argc, const char * sz[] )
{
return 0;
}