如何键入定义包装模板的智能指针 class
How to typedef a smart pointer wrapping a template class
如何键入定义 std::unique_ptr<T>
,其中 T
是模板 class Object<U>
?
我有一个模板class,Object.h:
template<typename T>
class Object
{
public:
Object() {}
~Object() {}
T getValue() { return value_; }
void setValue(T value) { value_ = value; }
private:
T value_;
}
还有另一个 class 称为 Holder,它在容器中保存一个包裹在智能指针 std::unique_ptr<Object<T>>
中的对象:
template<typename T>
class Holder
{
public:
Holder() {}
~Holder() {}
private:
std::vector<std::unique_ptr<Object<T>>> objects_;
}
我总是使用 typedef 来引用包裹在智能指针中的对象,所以我将以下 typedef 放在 class 定义中:
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 ´<´
。
执行此操作的正确方法是什么?
如果我对你想要实现的目标是正确的,一个解决方案是声明一个 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 的解决方案更简单的解决方案。
可能你想要的只是:
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
不需要自己的参数,因为它使用包含 class.
的 T
在 class 定义中,定义的 typedef 不需要在引用时使用类型名 T 进行参数化,只需直接替换 ObjectPtr 即可:
无效:
std::vector<ObjectPtr<T>> objects_;
作品:
std::vector<ObjectPtr> objects_;
如何键入定义 std::unique_ptr<T>
,其中 T
是模板 class Object<U>
?
我有一个模板class,Object.h:
template<typename T>
class Object
{
public:
Object() {}
~Object() {}
T getValue() { return value_; }
void setValue(T value) { value_ = value; }
private:
T value_;
}
还有另一个 class 称为 Holder,它在容器中保存一个包裹在智能指针 std::unique_ptr<Object<T>>
中的对象:
template<typename T>
class Holder
{
public:
Holder() {}
~Holder() {}
private:
std::vector<std::unique_ptr<Object<T>>> objects_;
}
我总是使用 typedef 来引用包裹在智能指针中的对象,所以我将以下 typedef 放在 class 定义中:
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 ´<´
。
执行此操作的正确方法是什么?
如果我对你想要实现的目标是正确的,一个解决方案是声明一个 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 的解决方案更简单的解决方案。
可能你想要的只是:
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
不需要自己的参数,因为它使用包含 class.
T
在 class 定义中,定义的 typedef 不需要在引用时使用类型名 T 进行参数化,只需直接替换 ObjectPtr 即可:
无效:
std::vector<ObjectPtr<T>> objects_;
作品:
std::vector<ObjectPtr> objects_;