2016-10-01 51 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