2015-11-03 19 views
4

我想写一个通用的模板方法,计算一些东西,最后返回值typename T。该值来自QString,所以我需要将QString转换为指定的typename T。不幸的是我只能找到toDouble(),toInt() ......方法。如何使用模板将QString转换为typename?

我需要的是:

QString s = 3.1415; 
double d = s.toType<double>(); 
float f = s.toType<float>(); 
int i = s.toType<int>(); 

我不想叫toDouble()toInt(),......因为我不能在编译时选择它们。

谢谢!


编辑:我可以写做的正是这个我自己专门的模板函数。所以

double myOwnConvertFunction<double>(const QString& s) 

会那么简单地调用s.toDouble()

我认为Qt的可能已经有一个内置的方式吗?

+1

QVariant(s).value ()可以在这里工作。 –

+0

听起来不错,但这是否会影响性能? QString在之前被转换为QVariant,对吗? – FrozenTarzan

+0

afaik qvariant类可以将字符串的dptr直接存储在本地并与之共享,从而避免进一步堆分配成本。你可以检查源代码是绝对肯定的。 –

回答

6

您可以转换的QString到QVariant然后使用值()

QVariant(s).value<T>() 

QVariant与QString共享数据,因此不会发生深度复制e,结果应该相当快。为了更加舒适,Qt有

qvariant_cast<T>(s) 
1

你可以写一个非成员toType

template <typename T> struct type { }; 

template <typename T> 
auto toType(QString const& q) 
    -> decltype(toType(q, type<T>{})) 
{ 
    return toType(q, type<T>{}); 
} 

与一群重载酌情:

double toType(QString const& q, type<double>) { 
    return q.toDouble(); 
} 

int toType(QString const& q, type<int>) { 
    return q.toInt(); 
} 

float toType(QString const& q, type<float>) { 
    return q.toFloat(); 
} 

... 
2

你要使用QTextStream。您可以使用QTextStreamQString constructor。您的代码可能会是这个样子:

template <typename T> 
T toType(const QString& string) { 
    T result; 
    QTextStream stream(&string, QIODevice::ReadOnly); 

    stream >> result; 
    return result; 
} 

顺便说一句,这取决于你是从pre-gcc 5.0 stringstream move-constructor bug痛苦,你也可以完成QTextStream建设直列像这样:

template <typename T> 
T toType(const QString& string) { 
    T result; 

    QTextStream(&string, QIODevice::ReadOnly) >> result; 
    return result; 
} 
+0

嗨乔纳森。从风格的角度来看,这看起来很不错,但我担心它存在性能问题。我会研究约翰内斯绍布的建议(请参阅我的问题的评论)。 – FrozenTarzan