2017-02-27 78 views
2

假設我們有以下功能:是否可以將一個向量<shared_ptr <T>>傳遞給const向量<shared_ptr <const T>>&參數?

void doStuff(const std::vector<std::shared_ptr<const Foo>>& fs) { } 

有沒有一種辦法(安全)傳遞一個std::vector<std::shared_ptr<Foo>>這個參數?例如:

std::vector<std::shared_ptr<Foo>> foos; 
doStuff(foos); 

這種隱式轉換失敗,但可以通過強制轉換安全地完成嗎? (這看起來理論上是安全的,因爲doStuff函數將無法修改矢量,也不能修改其中的對象。)

+0

我發現使const items的shared_ptr增加了不必要的複雜性。但我不認爲你可以做到這一點沒有黑客。 –

+0

這是明確未定義的行爲。內存佈局明智可能*看起來像*它應該每次都有效,但是你不能依賴它。誰知道編譯器可能做什麼轉換,包括消除呈現未定義行爲的任​​何代碼。 –

+0

什麼是未定義的行爲?我的問題中的代碼沒有編譯,所以也許你是指一些假設的'const_cast'? – jtbandes

回答

2

簡短答案是「否」。

給定一個類模板

template <typename T> struct Foo {}; 

Foo<int>Foo<const int>兩種不同的類型。這兩種類型之間沒有隱式轉換。

我的建議是製作doStuff函數模板。

template <typename T> 
void doStuff(const std::vector<T>& fs) { } 

template <typename T> 
void doStuff(const std::vector<std::shared_ptr<T>>& fs) { } 

如果你沒有修改doStuff,從doStuff複製代碼shared_ptr<Foo>的選擇可能是唯一可以做的事情理智。

+0

我明白隱式轉換不起作用,但我問是否有某種方法可以在這裏安全地使用顯式轉換。 – jtbandes

+0

作爲一種解決方法,它可能值得研究'std :: transform'(http://en.cppreference.com/w/cpp/algorithm/transform)並更改doSomething一次獲取一個項目並將其轉換爲適當的類型。 – moka

0

不,但你可以做的是改變你的界面,使其更具包容性。你寫:

void doStuff(std::vector<std::shared_ptr<Foo const>> const& fs) { } 

但你真正想要的只是一些連續的範圍std::shared_ptr<const Foo>對不對?因此,讓我們改變,要:

void doStuff(gsl::span<std::shared_ptr<Foo const>> fs) { } 

但後來真的,我們需要共享自己的指針指向const還是不夠,他們是const

void doStuff(gsl::span<std::shared_ptr<Foo> const> fs) { } 

現在我們有一個接口,我們可以調用​​。

相關問題