模板仅适用于智能指针

Template only for smart pointer

本文关键字:智能 指针 适用于      更新时间:2023-10-16

嗨,我不确定这是可能的,因为我想问,因为可能有更好的方法来实现类似的东西,我不知道。为简单起见,我们假设VectorT

template<class T>
class VectorT: private std::vector<T>`

对我想要的东西的尝试是沿着。

namespace detail
{
template<class SmartPtr>
class MyClassVectorBase : public VectorT<SmartPtr>
{
public:
    MyClassVectorBase() = default;
    // all common functions of MyVectorView and MyVector
};
}
using MyClassVectorView = detail::MyClassVectorBase<nonstd::observer_ptr<SomeClass>>;
class MyVector : public detail::MyClassVectorBase<std::unique_ptr<SomeClass>>
{
    // only functions related to the actual owner vector
};

我希望的是MyClassVectorBase只能在智能指针类型上被模板化,并且只接受SomeClass。我想用专门化是可以的但是我不知道这类东西的语法是什么

template<class T, class SmartPtr>
class MyClassVectorBase : public VectorT<SmartPtr<T>>
{
};
template<SomeClass T, typename SmartPtr>
class MyClassVectorBase : public VectorT<SmartPtr<T>>
{   
};

这样的事情可能吗?

编辑:好的,让我试着解释一下这个和它背后的逻辑。我需要一个Foo对象的向量。只有Foo,没有别的。在一种情况下,类将是对象的所有者,并具有一些额外的函数。因为它是船东,所以船级是MyClassVector : public VectorT<std::unique_ptr<Foo>>然后我必须以某种方式操作这些物体,但这些不会被拥有。所有权是单一的,并且总是比我将要操作的对象更长寿,所以不需要shared_ptr。那么我想我的课将是一个"视图类"MyClassVectorView : public VectorT<std::observer_ptr<Foo>>而不是observer_ptr,它也可以说是原始ptr,但它的意图是更好的。现在MyClassVectorView将与MyClassVector具有所有相同的功能,这就是为什么我认为我将继承它。

要做到这一点,我需要一个基类,将接受unique_ptrobserver_ptr。这样我就可以避免重复了只要我能输入MyClassVector : public MyClassVectorView<std::unique_ptr<Foo>>

另一种选择是有一个类,用SFINAE检测模板参数是否为unique_ptr,然后启用额外的函数。这将避免额外的继承。

不确定你想获得什么,但我怀疑你需要模板模板参数。

我想你可以声明(但不定义)MyClassVectorBase作为接收单个模板typename参数

template <typename>
class MyClassVectorBase;

和next定义了一个基于模板的专门化;就像

template <template<typename...> class SmartPtr, typename Foo>
class MyClassVectorBase<SmartPtr<Foo>> : public VectorT<SmartPtr<Foo>>
{
public:
    MyClassVectorBase() = default;
    void doSomething(){}
    void doSomething2(){}
};

如果Foo不是模板参数,而是Foo struct,你可以写

template <template<typename...> class SmartPtr>
class MyClassVectorBase<SmartPtr<Foo>> : public VectorT<SmartPtr<Foo>>
{
public:
    MyClassVectorBase() = default;
    void doSomething(){}
    void doSomething2(){}
};

你的例子修改和集成(与main()和假observer_ptr)

#include <iostream>
#include <string>
#include <vector>
#include <memory>
namespace nonstd
 {
   template <typename T>
   struct observer_ptr
    { };
 }
template <class T>
class VectorT
{
public:
    // expose nececssary functions
private :
    std::vector<T> container_;
};
struct Foo{
    double x;
};
template <typename>
class MyClassVectorBase;
// this class should only accept smart pointers of Foo
template <template<typename...> class SmartPtr, typename Foo>
class MyClassVectorBase<SmartPtr<Foo>> : public VectorT<SmartPtr<Foo>>
{
public:
    MyClassVectorBase() = default;
    void doSomething(){}
    void doSomething2(){}
};
using MyClassVectorView = MyClassVectorBase<nonstd::observer_ptr<Foo>>;
class MyVector : public MyClassVectorBase<std::unique_ptr<Foo>>
{
    // function only for this class but still inheriting all MyClassVectorBase stuff
};
int main ()
 {
 }