Shmoopy
Shmoopy

Reputation: 5534

Tracking memory consumption of a template class

I have a class for which I'd like an estimation of how much memory it's consuming:

template <typename T, typename U>
class MyTemplateClass
{
    size_t EstimateMemoryConsumption() const
    {
        // the memory consumption is a function of the size of the first template argument
        return f(sizeof(T));
    }
}

And this works fine. Recently I've been asked to support T == std::string. The current implementation doesn't work because sizeof(std::string) doesn't reflect the memory consumption of an std::string (I need to call capacity() on the std::string). According to this, I cannot give a partial specialization for the member function (for T == std::string, and any U)

Is there a different way to achieve this?

Upvotes: 1

Views: 222

Answers (2)

keith
keith

Reputation: 5352

Use traits to achieve specialization:

template <typename T>
class MyTemplateClassTraits
{
public:
    static size_t EstimateMemoryConsumption(T& member)
    {
        return 0; // implement...
    }
};

template <>
class MyTemplateClassTraits<std::string>
{
public:
    static size_t EstimateMemoryConsumption(std::string& member)
    {
        return 0;  // implement...
    }
};

Without changing your current API:

template <typename T, typename U>
class MyTemplateClass
{
    //...

    size_t EstimateMemoryConsumption() const
    {
        // the memory consumption is a function of the size of the first template argument
        return MyTemplateClassTraits<T>::EstimateMemoryConsumption(t_data_member);
    }

    //...
}

Upvotes: 1

Vittorio Romeo
Vittorio Romeo

Reputation: 93364

You could make memory consumption a function of the template parameter itself.

template <typename T, typename U>
class MyTemplateClass
{
    size_t EstimateMemoryConsumption() const
    {
        return estimate<T>(my_data_member);
    }
};

template <typename T>
size_t estimate(const T&) noexcept { return sizeof(T); }

template <>
size_t estimate<std::string>(const std::string& x) noexcept 
{ 
    return x.capacity(); 
}

Upvotes: 2

Related Questions