C++ 仅针对单个函数的部分模板专门化

C++ 仅针对单个函数的部分模板专门化,c++,c++11,templates,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 = a

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

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);
}
class FOO{};
类ItemGetter{
虚拟FOO*GetItem(int索引)=0;
};
模板
类ArrayContainer:PublicItemGetter{
T*阵列;
阵列容器(T*阵列){
这个->数组=数组;
}
/*
*还有很多其他的功能。
*我只想写一次
* ....
*/
/*如果T参数是实例类型*/
FOO*GetItem(整数索引){
return&此->数组[索引];
}
/*如果T参数是指针类型*/
FOO*GetItem(整数索引){
返回此->数组[索引];
}
};
无效用法(){
FOO-FOO数组[100];
FOO*foopointerray[100];
auto bar1=阵列容器(fooArray);
auto bar2=阵列容器(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);
}
#包括
类FOO{};
模板
T*get\u T(T*array,std::size\u T index)
{
返回数组+索引;
}
模板
T*get\u T(T**数组,std::size\u T索引)
{
返回数组[索引];
}
模板
类数组容器{
T*阵列;
公众:
阵列容器(T*阵列)
:数组(数组)
{
}
/*
*还有很多其他的功能。
*我只想写一次
* ....
*/
自动获取项目(标准::大小索引)
{
返回get(数组、索引);
}
};
无效用法(){
FOO-FOO数组[100];
FOO*foopointerray[100];
auto bar1=阵列容器(fooArray);
auto bar2=阵列容器(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);
}
#包括
类FOO{};
结构ArrayContainerServices
{
模板
静止的
T*ImplementGetItem(T*array,std::size\u T index)
{
返回数组+索引;
}
模板
静止的
T*ImplementGetItem(T**数组,标准::大小\u T索引)
{
返回数组[索引];
}
};
模板
类数组容器
:private ArrayContainerServices//注意-私有继承
{
T*阵列;
公众:
阵列容器(T*阵列)
:数组(数组)
{
}
/*
*还有很多其他的功能。
*我只想写一次
* ....
*/
自动获取项目(标准::大小索引)
{
返回ImplementGetItem(数组、索引);
}
};
无效用法(){
FOO-FOO数组[100];
FOO*foopointerray[100];
auto bar1=阵列容器(fooArray);
auto bar2=阵列容器(fooPointerArray);
FOO*f=bar1.GetItem(2);
f=bar2.GetItem(5);
}

遵从重载自由函数:

#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);
}
#包括
类FOO{};
模板
T*get\u T(T*array,std::size\u T index)
{
返回数组+索引;
}
模板
T*get\u T(T**数组,std::size\u T索引)
{
返回数组[索引];
}
模板
类数组容器{
T*阵列;
公众:
阵列容器(T*阵列)
:数组(数组)
{
}
/*
*还有很多其他的功能。
*我只想写一次
* ....
*/
自动获取项目(标准::大小索引)
{
返回get(数组、索引);
}
};
无效用法(){
FOO-FOO数组[100];
FOO*foopointerray[100];
auto bar1=阵列容器(fooArray);
auto bar2=阵列容器(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);
}
#包括
类FOO{};
结构ArrayContainerServices
{
模板
静止的
T*ImplementGetItem(T*array,std::size\u T index)
{
返回数组+索引;
}
模板
静止的
T*ImplementGetItem(T**数组,标准::大小\u T索引)
{
返回数组[索引];
}
};
模板
类数组容器
:private ArrayContainerServices//注意-私有继承
{
T*阵列;
公众:
阵列容器(T*阵列)
:数组(数组)
{
}
/*
*还有很多其他的功能。
*我只想写一次
* ....
*/
自动获取项目(标准::大小索引)
{
返回ImplementGetItem(数组、索引);
}
};
无效用法(){
FOO-FOO数组[100];
FOO*foopointerray[100];
auto bar1=阵列容器(fooArray);
auto bar2=阵列容器(fooPointerArray);
FOO*f=bar1.GetItem(2);
f=bar2.GetItem(5);
}

T==U
T==U*
时,是否希望
GetItem
返回一个
U
?我不会那样做,因为这违背了我的期望。如果我有一个
T
的容器,那么我想插入并检索
T
s而不是
T*
T
,并移除指针。如果所有出现的
T
都显示为
T*
,那么我想你最好删除
*
,让用户决定是存储指针还是对象。指针类型是什么意思?只是(cv限定)
FOO*
,还是包含智能指针?@tobi303这很好,但在我的情况下是不可能的。我的情况比我的例子要复杂一点……难道
T
FOO
/
FOO*
不同吗?因为不允许方法的部分专门化,但允许完全专门化。当
T==U
T==U*
时,是否希望
GetItem
返回
U
?我不会那样做,因为这违背了我的期望。如果我有一个
T
的容器,那么我想插入并检索
T
s而不是
T*
T
,并移除指针。如果所有出现的
T
都显示为
T*
,那么我想你最好删除
*
,让用户决定