仅适用于单个功能的部分模板专业化

Partial template specialization only for a single function

本文关键字:专业化 适用于 单个 功能      更新时间:2023-10-16

我有一个模板,我想将指针类型或实例类型作为模板参数。一个例子:

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);
}

我如何专门为指针和实例变体的GetItem()函数(不写两次其他所有功能)?

延迟到超载的免费功能:

#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);
}

或,为了更好地封装,从导出Getter函数过载的服务类中私下派生为静态成员。

#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);
}