如何键入一个包装模板类的智能指针

时间:2015-10-24 17:43:08

标签: templates c++11 typedef smart-pointers

如何输入std::unique_ptr<T>,其中T是模板类Object<U>

我有一个模板类,Object.h:

    template<typename T>
    class Object
    {
    public:
       Object()                      {}
       ~Object()                     {}

       T getValue()                  { return value_; }
       void setValue(T value)        { value_ = value; }

    private:
       T value_;
    }

另一个名为Holder的类,它在一个容器中保存一个用智能指针std::unique_ptr<Object<T>>包裹的Object:

    template<typename T>
    class Holder
    {
    public:
       Holder()                      {}
       ~Holder()                     {}

    private:
       std::vector<std::unique_ptr<Object<T>>> objects_;
    }

我总是使用typedef来引用智能指针中包含的对象,所以我将以下typedef放在类定义中:

    template<typename T>
    class Holder
    {
       typedef std::unique_ptr<Object<T>> ObjectPtr; // - (1)
      // using  ObjectPtr = std::unique_ptr<T, Object<T>> - (2) alias template - same error as above
      // typedef std::unique_ptr<Object<T>> ObjectPtr<T> - not allowed
      // ..

     private:
        std::vector<ObjectPtr<T>> objects_;

但是,将成员变量objects_的类型更改为ObjectPtr<T>会导致编译器错误C2947: expecting ´>´ to terminate template-argument-list, found ´<´

这样做的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

如果我对你想要达到的目标是正确的,那么解决方案就是宣布alias template

template<typename T>
class Holder
{
public:
    template<typename U>
    using ObjectPtr = std::unique_ptr<Object<U>>;

    void add_objet(ObjectPtr<T> newObject)
    { objects_.emplace_back(std::move(newObject)); }

private:
    std::vector<ObjectPtr<T>> objects_;
};

int main()
{
    Holder<int> holder;
    holder.add_objet( make_unique<Object<int>>() );
}

修改

因为我的解决方案在主模板中定义了一个内部模板,所以它有点过分且有点麻烦:在主模板中,每个ObjectPtr的使用必须由T参数化。请参阅下面提出的基于typedef的解决方案其他贡献者可以使用更简单的解决方案。

答案 1 :(得分:1)

可能你想要的只是:

template<typename T>
class Holder
{
   typedef std::unique_ptr<Object<T>> ObjectPtr; // - (1)

   void add_object( ObjectPtr newObject )
   { objects_.emplace_back(std::move(newObject)); }

 private:
    std::vector<ObjectPtr> objects_;
};

int main()
{
    Holder<int> holder;
    holder.add_object(make_unique<Object<int>>());
}

请注意Holder<T>::ObjectPtr不需要自己的参数,因为它使用了包含类的T

答案 2 :(得分:1)

在类定义中,引用时不需要使用typename T对定义的typedef进行参数化,只需直接替换ObjectPtr:

不起作用:

std::vector<ObjectPtr> objects_;

使用:

ComboBox1_Change