2012-09-15 91 views
1

我對std::shared_ptr<T>使用了很多不同的類型。由於我想將所有這些不同的shared_ptr s存儲在一個矢量中,因此我認爲必要時可以使用std::vector<std::shared_ptr<void> >並從void投射。類比std :: shared_ptr中的「cast from/to void」

我熟悉下面的「裸指針」使用

#include <iostream> 

void print(void* void_ptr) 
{ 
    int* int_ptr = static_cast<int*>(void_ptr); 
    std::cerr << *int_ptr << std::endl; 
} 

int main() 
{ 
    int* int_ptr = new int(4); 
    void* void_ptr = static_cast<void*>(int_ptr); 
    print(void_ptr); 
    delete int_ptr; 
} 

這與g++完美的作品和AFAIK它,如果你有裸指針,這樣做的正確方法。但是現在我想和std::shared_ptr一樣。

#include <iostream> 
#include <memory> 

void print(std::shared_ptr<void> void_ptr) 
{ 
    std::shared_ptr<int> int_ptr = ??(void_ptr); // simple cast won't work 
    std::cerr << *int_ptr << std::endl; 
} 

int main() 
{ 
    std::shared_ptr<int> int_ptr = std::make_shared<int>(4); 
    std::shared_ptr<void> void_ptr = ??(int_ptr); // same problem here 
    print(void_ptr); 
} 

這甚至有可能嗎?有很多不同的類型,我有shared_ptr s,但這些類型幾乎沒有共同之處。他們不會共享一個基類或類似的東西(如果這是唯一的方法,我會這樣做,但它會更確切地用某種類型的shared_ptr<void>)。

+1

您可能想閱讀以下問題/答案:http://stackoverflow.com/questions/5913396/why-do-stdshared-ptrvoid-work。我在這個特定的問題上或多或少是一個新手,所以我沒有知識可以分享,但該鏈接上的信息可以幫助您達成可行的解決方案。 – paercebal

+0

如果他們沒有任何共同之處......你爲什麼想把'void *'傳給他們呢?一般來說,如果你使用'void *',那麼某些事情可能會變得非常糟糕,或者你試圖從一個函數的簽名中得到一個類型(例如:理論上可以採用任何類型的函數,以便它可以將它傳遞給一個需要特定類型的函數)。對於後者,你應該使用'boost :: any',這是類型安全的。 –

+0

@NicolBolas:基本上我想將「數學」與「代碼」分開。我有代表數學結構的類。在每個這樣的類中,必須有一個類「Foo」中的對象。現在我想要一個讓'foo'對象訪問數學對象但不知道所有對象的圖層。我關心正確的使用,我認爲無效*是指「我有一個指向我想要傳遞的東西,卻不知道它到底是什麼。」我不想使用'boost'。 – stefan

回答

1

std::static_pointer_cast執行此功能。但是,這通常是一個非常糟糕的主意 - 爲什麼不是boost::anyboost::variant什麼?這種弱類型和弱執行的代碼只會讓你陷入屁股。

0

您的問題的最佳解決方案可能是type erasure

視爲C++不允許模板之間的隱式轉換(即使它們的參數是可轉換的)。

所以你可以做的是定義一個通用的接口,你將握在容器(operator*operator->對於初學者),並不僅僅是使用薄模板類在shared_ptr的類型擦除的目的。

編輯:

如問題@paercebal規定指出你,shared_ptr可以自己進行類型擦除,當模板參數是void。所以你也應該考慮一下。

+0

我似乎沒有得到「類型擦除」。據我瞭解你的鏈接文章,它似乎只是一個普通的基類。是對的嗎? – stefan

+0

簡而言之,是的。 你所做的是用基類定義接口,並創建一個實現它的模板。 通過這種方式,您可以獲得通用接口的優點,而無需爲可容納的類型強制執行通用基類。 – StoryTeller