[Solved] Template Function Fails to Compile



  • I've created a template function to write settings to a file, and I'm having a somewhat frustrating issue. Here's how I wanted to set it up:

    @
    template<typename S>
    void Settings::PutSetting(QString description, QFile *file, S setting)
    {
    QString settingString;
    if(typeid(setting) != typeid(QString))
    settingString = QString::number(setting);
    else
    settingString = setting;
    file->write(QByteArray(description.toAscii()) + QByteArray(" = ") + settingString.toAscii() + QByteArray("\n"));
    }
    @

    It worked fine for bool, int, and float types, but when I tried to pass a QString I got this compiler error:

    bq. settings.cpp:475:2: error: no matching function for call to 'QString::number(QString&)'

    Even if I change the condition in the if statement to one that will never be true, the error persists. This doesn't make any sense to me, because that particular piece of code will never be applied to a QString.

    Here's what I did to get the code to compile. It works just as I expected, but I would like to understand why my first attempt failed. Any Ideas?

    @
    template<typename S>
    void Settings::PutSetting(QString description, QFile file, S setting)
    {
    QString settingString;
    S settingPtr = new S(setting);
    if(typeid(setting) == typeid(float))
    settingString = QString::number(
    (reinterpret_cast<float
    >(settingPtr)));
    else if(typeid(setting) == typeid(int))
    settingString = QString::number((reinterpret_cast<int>(settingPtr)));
    else if(typeid(setting) == typeid(bool))
    settingString = QString::number((reinterpret_cast<bool>(settingPtr)));
    else
    settingString = setting;
    file->write(QByteArray(description.toAscii()) + QByteArray(" = ") + settingString.toAscii() + QByteArray("\n"));
    }
    @



  • LE:
    You can't use typeid in as condition in template class, you must either exclude that form compilation using #if... #endif or use a template specialization.

    The typeid in your particular case won't work because it's a run-time type identifier and templates are generated at compile-time.
    So the template specialization for QString is an option that works:
    @template<typename S>
    void Settings::PutSetting(QString description, QFile *file, S setting)
    {
    QString settingString;
    settingString = QString::number(setting);
    file->write(QByteArray(description.toAscii()) + QByteArray(" = ") + settingString.toAscii() + QByteArray("\n"));
    }

    template<>
    void Settings::PutSetting<QString>(QString description, QFile *file, QString setting)
    {
    QString settingString;
    settingString = setting;
    file->write(QByteArray(description.toAscii()) + QByteArray(" = ") + settingString.toAscii() + QByteArray("\n"));
    }@



  • Thanks for clearing that up. It makes sense now, and I can stop banging my head against the wall. The code you posted also works perfectly.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.