c++ - 仅针对单个函数的部分模板特化

标签 c++ c++11 templates

我有一个模板,我想在其中使用指针类型或实例类型作为模板参数。一个例子:

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 函数重载导出为静态成员的服务类私有(private)派生。

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

关于c++ - 仅针对单个函数的部分模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47678237/

相关文章:

c++ - 具有所有函数参数的转换构造函数的类模板

使用模板的 C++ 静态分派(dispatch)

c++ - 将 Objective-C 的参数发送到 C++

c++ - 用opencv放大图像像素

c++ - 委托(delegate)构造函数抛出时是否调用析构函数?

C++ thread assignment throwing SIGSEGV 收藏

c++ - 返回其自身类型的模板类方法的正确签名

c++ - 测试构造函数初始化列表

c++ - 如果玩家在附近,将幽灵移向迷宫中的玩家?

c++ - C++11 标准中的哪个子句允许我在下面的 `A` 中删除 `return` 语句中的 `A::operator-()`?