2017-07-18 3 views
0

J'essaie d'implémenter une sorte de StringBuilder pour certains tests unitaires. Le problème est que j'utilise fortement QByteArray dans certains modèles, qui utilise le StringBuilder pour la journalisation. Afin d'utiliser QByteArray dans un QString().arg() je dois généralement envelopper le tableau d'octets avec QString(...).échecs de surcharge de fonction de modèle variad

J'ai donc essayé les éléments suivants:

const char* buildCString(const QString& msg){ 
    return msg.toLatin1().toStdString().data(); 
} 

template<typename Head, typename ...Tail> 
const char* buildCString(const QString& msg, const Head& arg, const Tail&... rest){ 
    return buildCString(msg.arg(arg), rest...); //generic use case 
} 

template<typename Head, typename ...Tail> 
const char* buildCString(const QString& msg, const QByteArray& arg, const Tail&... rest){ 
    return buildCString(msg.arg(QString(arg)), rest...); 
} 

void main(){ 
    auto data = buildCString("double %1, QByteArray %2, int %3", 0.123, QByteArray("Test"), 2); 
    cout << "Data: " << data << endl; 
} 

Et l'erreur suivante:

In instantiation of 'const char* buildCString(QString, Head, Tail ...) [with Head = QByteArray; Tail = {int}]': 
required from 'const char* buildCString(QString, Head, Tail ...) [with Head = double; Tail = {QByteArray, int}]' 
required from here 
Fehler: call of overloaded 'arg(QByteArray&)' is ambiguous 
    return buildCString(msg.arg(arg), rest...); 

Ainsi, la fonction générique est appelée au lieu de celui plus spécialisé.

Ma question est la suivante: pourquoi la surcharge ne se déclenche-t-elle pas? J'ai le sentiment que je manque quelque chose de fondamental ici, mais après avoir cherché plusieurs heures pour trouver une solution, je n'arrive toujours pas à la contourner. J'utilise Qt 5.9.0 et mingw32 5.3.0 32Bit.

Répondre

1

Dans cette surcharge ...

template<typename Head, typename ...Tail> 
const char* buildCString(const QString& msg, const QByteArray& arg, const Tail&... rest){ 
    return buildCString(msg.arg(QString(arg)), rest...); 
} 

... le paramètre de modèle Head ne peut jamais être déduit. Vous devriez vous en débarrasser.

+0

C'était tout, merci! BTW, j'ai vu quelque chose comme ça ici: https://stackoverflow.com/questions/40687615/variadic-template-function-overloading pourquoi est-il valable là? – RyanMcFlames

+0

@RyanMcFlames Parce qu'il fournit l'argument template sur le site d'appel (foo (args ...)). Vous auriez pu le faire aussi bien avec buildCString (...). –