1 year ago

#139383

test-img

Diz

Add function template specialisation for double types only in a template class

I have an implementation of a class template with a base class.

class MyBase
{
protected:
    virtual void getErrorPercent(std::ostream& fileStream) = 0;
    virtual void getFormattedText(std::ostream& fileStream) = 0;
};

template <class T>
class MyClass : public MyBase
{
protected:
    void getErrorPercent(std::ostream& fileStream) override
    void getFormattedText(std::ostream& fileStream) override
private:
    std::string getErrorPercentageStr();
    T m_expected;
    T m_measured;
};

In cpp [moved from in class]:

template <class T>
std::string MyClass<T>::getErrorPercentageStr()
{
    return "";
}

template <class T>
void MyClass<T>::getErrorPercent(std::ostream& fileStream)
{
    // Default for any type is to do nothing
}

template <class T>
void MyClass<T>::getFormattedText(std::ostream& fileStream)
{
    fileStream << "Measured " << m_measured << ", Expected " << m_expected;
}

I want to add function template specialisation for getErrorPercent, getFotmattedText and getErrorPercentageStr for double types only.

For getErrorPercent I want to:

template<>
void MyClass<double>::getErrorPercent(std::ostream& fileStream)
{
   fileStream << " Error " << getErrorPercentageStr() << std::endl;
}

For getFotmattedText I want to:

template<>
void MyClass<double>::getFormattedText(std::ostream& fileStream)
{
   fileStream << "Measured " << m_measured << ", Expected " << m_expected
       << " [Error " << getErrorPercentageStr() << "]";
}

The getErrorPercentageStr function for double will calculate the error [m_measured and m_expected will be doubles] and return it as a string. For all other types it will return an empty string.

template<>
std::string MyClass<double>::getErrorPercentageStr();
{
    std::ostringstream rep;
    double difference = m_measured - m_expected;
    if (m_expected == 0.0)
    {
        rep << difference << "V";
    }
    else
    {
        double error = (difference / m_expected) * 100.0;
        if (std::abs(error) < 100.0)
        {
            rep << error << "%";
        }
        else
        {
            rep << difference << "V";
        }
    }
    return rep.str();
}

I have been searching for a solution but can't get it to either compile or call the correct function for double.

How/where do I put specialised versions of the functions? I don't think I can put these in the class itself.

In the h or cpp file?

Can I leave the main implementations of the functions [non specialised] in the class?

Do i need to put prototypes somewhere for the specialised functions?

template<> std::string MyClass<double>::getErrorPercentageStr();
template<> void MyClass<double>::getErrorPercent(std::ostream& fileStream);
template<> void MyClass<double>::getFormattedText(std::ostream& fileStream);

And then implement in cpp?

I tried this and get lots of "unresolved external symbol" for int versions of MyClass::getFormattedText() and MyClass::getErrorPercent(). Also for bool, unsigned int and std::basic_string versions too. All these should use the default version.

How do I fix these?

I did get it working with "if constexpr (std::is_same_v<T, double>)" to process it but this failed to compile with vxWorks. Complained about << for double in getErrorPercentageStr where "rep << difference << "V";".

error: no match for 'operator<<' (operand types are 'std::ostringstream' and 'double')

Any help would be greatly appreciated!

c++

specialization

function-templates

explicit-specialization

function-templates-overloading

0 Answers

Your Answer

Accepted video resources