Home Partial template specialization only for a single function
Reply: 1

Partial template specialization only for a single function

powerpete
1#
powerpete Published in 2017-12-06 15:46:16Z

I've a template where I want to use a pointer type or an instance type as the template parameter. An Example:

class FOO {};

class ItemGetter {
    virtual FOO * GetItem(int index) = 0;
};

template<class T>
class ArrayContainer : public ItemGetter {
    T *array;
    ArrayContainer(T * array) {
        this->array = array;
    }

    /*
     * A lot of other functions.
     * I want to write them only once
     * ....
     */

    /* If the T Parameter is an instance Type */
    FOO * GetItem(int index) {
        return &this->array[index];
    }
    /* If the T Parameter is an pointer Type */
    FOO * GetItem(int index) {
        return this->array[index];
    }
};

void usage() {
  FOO fooArray[100];
  FOO * fooPointerArray[100];

  auto bar1 = ArrayContainer<FOO>(fooArray);
  auto bar2 = ArrayContainer<FOO*>(fooPointerArray);
}

How can I specialize the GetItem() function for the pointer and the instance variant (without writing all the other functions twice)?

Richard Hodges
2#
Richard Hodges Reply to 2017-12-06 17:09:08Z

Defer to an overloaded free function:

#include <cstddef>

class FOO {};

template<class T>
T* get_t(T* array, std::size_t index)
{
    return array + index;
}

template<class T>
T* get_t(T** array, std::size_t index)
{
    return array[index];
}

template<class T>
class ArrayContainer {
    T *array;
public:
    ArrayContainer(T * array) 
    : array(array)
    {
    }

    /*
     * A lot of other functions.
     * I want to write them only once
     * ....
     */

     auto GetItem(std::size_t index)
     {
         return get_t(array, index);
     }

};

void usage() {
  FOO fooArray[100];
  FOO * fooPointerArray[100];

  auto bar1 = ArrayContainer<FOO>(fooArray);
  auto bar2 = ArrayContainer<FOO*>(fooPointerArray);

  FOO* f = bar1.GetItem(2);
  f = bar2.GetItem(5);
}

or, for better encapsulation, derive privately from a services class which exports the getter function overloads as static members.

#include <cstddef>

class FOO {};


struct ArrayContainerServices
{
    template<class T>
    static 
    T* ImplementGetItem(T* array, std::size_t index)
    {
        return array + index;
    }

    template<class T>
    static
    T* ImplementGetItem(T** array, std::size_t index)
    {
        return array[index];
    }
};

template<class T>
class ArrayContainer 
: private ArrayContainerServices  // note - private inheritance
{
    T *array;
public:
    ArrayContainer(T * array) 
    : array(array)
    {
    }

    /*
     * A lot of other functions.
     * I want to write them only once
     * ....
     */

     auto GetItem(std::size_t index)
     {
         return ImplementGetItem(array, index);
     }

};

void usage() {
  FOO fooArray[100];
  FOO * fooPointerArray[100];

  auto bar1 = ArrayContainer<FOO>(fooArray);
  auto bar2 = ArrayContainer<FOO*>(fooPointerArray);

  FOO* f = bar1.GetItem(2);
  f = bar2.GetItem(5);
}
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.33219 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO