如何实施atot()
,以便根据类型使用atof()
,atoi()
或atol()
?
目前,它对所有类型使用atof()
:
template<typename T>
T Mtx<T>::atot(const char *s) const
{
return atof(s);
}
请注意速度非常重要。
答案 0 :(得分: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");
}
答案 1 :(得分: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);
}
答案 2 :(得分: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 :(得分:2)
我真的不明白为什么你想要这个。调用正确的方法似乎同样容易。
但是如下所示呢?
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);
}
答案 4 :(得分:1)
如果类型出现在其中一个参数中,则可以重载函数。所以你需要一个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;
}