仅适用于智能指针的模板

时间:2016-10-01 00:31:54

标签: c++ templates c++11

嗨我不确定这是否可行,但我想问,因为可能有更好的方法来实现我不知道的类似的东西。 为简单起见,我们只考虑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对象的VectorT。只有Foo,没有别的。 在一种情况下,该类将是对象的所有者并具有一些额外的功能。 由于它是所有者,因此它将是MyClassVector : public VectorT<std::unique_ptr<Foo>>课程 然后我必须以某种方式操作这些对象,但这些不会被拥有。 所有权是单一的,并且总是比我将要操作的对象更长,所以不需要shared_ptr。 那么我想我的班级将成为一个&#34; View课程&#34; MyClassVectorView : public VectorT<std::observer_ptr<Foo>> 而不是observer_ptr它可以说是原始的ptr,但意图是更好的。 现在MyClassVectorView将具有MyClassVector所有相同的功能,这就是为什么我认为我会继承它。

为此,我需要一个能同时接受unique_ptrobserver_ptr的基类。 然后我可以避免重复,只要我可以做MyClassVector : public MyClassVectorView<std::unique_ptr<Foo>>

如果模板参数是unique_ptr,则替换将具有一个类并使用SFINAE进行检测,然后启用额外功能。这样可以避免额外的继承。

1 个答案:

答案 0 :(得分:0)

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

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

template <typename>
class MyClassVectorBase;

然后定义基于特化模板的模板;

之类的东西
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 ()
 {
 }
相关问题