производительность — Как разобрать строку в C ++ typename?

Как реализовать atot() так что он использует atof(), atoi(), или же atol() по типу?
В настоящее время он использует atof() для всех типов:

template<typename T>
T Mtx<T>::atot(const char *s) const
{
return atof(s);
}

Обратите внимание, что скорость очень важна.

3

Решение

Самым простым решением является специализация:

template<>
double Mtx<double>::atot(const char *s) const
{
return atof(s);
}

template<>
int Mtx<int>::atot(const char *s) const
{
return atoi(s);
}
3

Другие решения

boost::lexical_cast<T> должен сделать это, в основном

template<typename T>
T Mtx<T>::atot(const char *s) const
{
return boost::lexical_cast<T>(s);
}

Демо-версия:

#include <boost/lexical_cast.hpp>

template<typename T>
T atot(const char *s)
{
return boost::lexical_cast<T>(s);
}

int main()
{
auto i = atot<int>("3");
auto d = atot<double>("-INF");
auto f = atot<double>("314e-2");
auto ul = atot<unsigned long>("65537");
}
3

Специализация — это создание специальных реализаций шаблона в зависимости от конкретного типа.

В этом случае вы можете сделать это:

template<>
float Mtx<float>::atot(const char *s) const
{
return atof(s);
}

template<>
int Mtx<int>::atot(const char *s) const
{
return atoi(s);
}

… и так далее

Так что если вы используете atot с float или с int, тогда будут использованы вышеуказанные реализации. Для любого другого типа будет использоваться тот, который у вас уже есть.

3

Я действительно не понимаю, почему вы этого хотите. Кажется, так же легко вызвать правильный метод.

Но как насчет чего-то вроде следующего?

void atot(const char *s, float& result)
{
result = atof(s);
}

void atot(const char *s, long& result)
{
result = atol(s);
}

void atot(const char *s, int& result)
{
result = atoi(s);
}
2

Вы можете перегрузить функцию, если тип указан в одном из параметров. Таким образом, вам потребуется параметр out вместо возвращаемого значения:

void atonum(const char*, int&);
void atonum(const char*, long&);
void atonum(const char*, float&);

Если вам не нравится это, вы можете использовать специализацию шаблона. Смотрите другие ответы об этом.

Или вы можете объединить перегрузку с шаблоном оболочки:

template<typename T> void atonum(const char* a)
{
T tmp;
atonum(a, tmp);
return tmp;
}

Но это по-прежнему ужасно называть специализированными шаблонами.

Вы можете получить более приятный синтаксис для вызывающей стороны, перегружая операторы преобразования типов.
Подтверждение концепции:

#include <cstdio>
#include <cstdlib>
struct atonum
{
atonum(const char* a):m_a(a){}
operator int(){printf("int\n"); return atoi(m_a);}
operator long(){printf("long\n"); return atol(m_a);}
operator float(){printf("float\n"); return atof(m_a);}
private:
const char* m_a;
};
int main(int argc, const char* argv[])
{
int i = atonum("1");
long l = atonum("2");
float f = atonum("3.0");
return i+l+f;
}
1
По вопросам рекламы [email protected]