2

如何减少模板专用类的代码重复?

我正在尝试创建一个类 ( MyArray),它的行为类似于std::vector但在某些函数中接收原始指针作为参数。

这是它的简化版本:-

template<class T> class MyArray{
    T database[10];
    public: T& get(int index){return database[index];}
    void set(int index, T t){
        database[index]=t;
    }
};
template<class T> class MyArray<std::unique_ptr<T>>{
    T* database[10];
    public: T*& get(int index){return database[index];}
    void set(int index, std::unique_ptr<T> t){
        T* tmp=t.release();
        database[index]=tmp;  
    }
};

是一个测试:-

class B{};
int main() {
    MyArray<B>   test1;
    MyArray<B*>  test2;
    MyArray<std::unique_ptr<B>> test3;
    test3.set(2,std::make_unique<B>()));
    return 0;
}

问题: 请演示一种优雅的方法来减少MyArray.

我希望的解决方案可能如下所示:-

template<class T> class MyArray{
    using U = if(T=std::uniquePtr<X>){X*}else{T};
    U database[10];
    public: U& get(int index){return database[index];}
    void set(int index, T t){
        U u = convert(t);//<-- some special function
        database[index]=u;
    }
};

可能存在一些内存泄漏/损坏。为简单起见,请忽略它。
我只想要一个想法/粗略的指南。(无需提供完整的可运行代码,但我不介意)

在现实生活中,有 20 多个函数,MyArray我希望对许多类进行相同的重构。

编辑:我(次要)编辑了一些代码和标签。感谢 AndyG 和 Jarod42。

4

2 回答 2

3

也许你可以将实现细节委托给你提供给你的类的结构,并且你专门化这个结构,而不是 MyArray:

template <typename T>
struct Policy {
  using type = T;
  static type convert(T t) { ... }
};

template <typename T>
struct Policy<std::unique_ptr<T>> {
  using type = T*;
  static type convert(T t) { ... }
};

template <typename T, typename P = Policy<T>>
class MyArray
{
  using type = typename P::type;

  void set(int index, T t) { type result = P::convert(t); }
};
于 2017-04-12T10:17:33.897 回答
1

您可能会考虑为通用功能使用通用基类:

template<class T>
class Base{
    protected:
    T database[10];
    public:
    T& get(int index){return database[index];} 
};

template<class T> 
class MyArray : public Base<T>{
    public:
    void set(int index, T t){
        this->database[index]=t;
    }
};

template<class T> 
class MyArray<std::unique_ptr<T>> : public Base<T*>
{
    public:
    void set(int index, std::unique_ptr<T>&& t){
        T* tmp=t.release();
        this->database[index]=tmp;   //a little different
    }
};

演示

于 2017-04-12T11:36:24.543 回答