2016-10-01 98 views
2

嗨我不确定这是可能的,但我想过要求,因为可能有更好的方法来实现类似的东西,我不知道。 为简单起见,您只需考虑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>> 
{ 
}; 

是一样的东西,即使是可能的吗?

编辑: 好吧,让我试着解释这个和它背后的逻辑。我需要一个VectorT的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>>

的alterantive将有一类与SFINAE检测如果模板参数是的unique_ptr,然后启用额外的功能。这将避免额外的继承。

+0

你可以使用std :: is_same来明确地检查所需的智能指针 – AndyG

+0

上述评论或者您可以将基础模板未定义并为SmartPtr提供模板专业化 DeiDei

+0

您似乎很认真地滥用继承。我想回答这个问题,但目前还不清楚你真正想做什么。你有'VectorT ',它只是从'std :: vector '私下继承而来。私人继承远比错误多得多,所以从一开始这就是一个相当不好的信号。 –

回答

0

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

我想你可以声明(但不是定义)MyClassVectorBase为接收一个模板类型名称参数

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不是一个模板参数,反而是Foostruct,你可以写

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() 
{ 
} 
+0

这绝对是在正确的轨道上,最肯定的工作,所以我接受它是正确的。我确实有问题,但我自己的类需要为unique_ptr添加删除器。最后,这是比较容易,尽管我不知道是否有与它'模板<模板类的SmartPtr> 类MyVector任何问题:公共VectorT <的SmartPtr > { 市民: \t无效doSomething1(){ } \t void doSomething2(){} }; MyVector v1; MyVector v2;' – xerion