【问题标题】:Reduce code duplication in class template specialization (array<Unique_ptr>)减少类模板特化中的代码重复 (array<Unique_ptr>)
【发布时间】:2026-01-05 22:55:01
【问题描述】:

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

我正在尝试创建一个类 (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;  
    }
};

Here 是一个测试:-

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

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

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

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

【问题讨论】:

  • 此代码不是 C++11...std::make_unique 是 C++14 功能。也许您使用的是 Visual Studio 2013 版本?
  • 不需要std::move(std::make_unique 中的move
  • @AndyG 鼓掌!我会尽快编辑它。谢谢。
  • @Jarod42 谢谢。这对我来说是新知识。我刚刚注意到我的代码还包含其他错误。我会尝试修复其中的一些。

标签: c++ templates c++14 template-specialization template-classes


【解决方案1】:

也许你可以将实现细节委托给你提供给你的类的结构,并且你专门化这个结构,而不是 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); }
};

【讨论】:

    【解决方案2】:

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

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

    Demo

    【讨论】:

    • 有趣的是,我刚刚注意到您更改了“Demo”的字体大小。 XD