[英]Deduce weak_ptr argument from shared_ptr
以下給了我編譯器錯誤:
無法從“std::shared_ptr”推導出“const std::weak_ptr<_Ty> &”的模板參數
#include <memory>
class Foo
{
public:
template<typename R>
void Bar(std::weak_ptr<R> const & p)
{
p;
}
};
int main(void)
{
auto foo = Foo();
auto integer = std::make_shared<int>();
foo.Bar(integer);
}
我試過,
template<typename R>
void Bar(std::weak_ptr<R::element_type> const & p)
{
}
,這在語法上似乎不正確。 以下工作,但我想知道是否有可能在 p 中進行轉換,而無需創建另一個臨時文件?
template<typename R>
void Bar(R const & p)
{
auto w = std::weak_ptr<R::element_type>(p);
}
為了清楚起見,我想明確聲明該函數應該采用 shared 或weak_ptr,所以我不喜歡 R const & p 解決方案。
為了完整起見,這當然也有效:
template<typename R>
void Bar(std::shared_ptr<R> const & p)
{
auto w = std::weak_ptr<R>(p);
}
std::weak<R>
的模板參數R
不能從std::shared_ptr<A>
的實例推導出,因為轉換構造函數(采用std::shared_ptr<Y>
)是一個構造函數模板,這意味着Y
可以可以是任何東西——並且無法從Y
(它被推導出為A
)推導出R
看看轉換構造函數。
你可以這樣寫:
template<typename T>
auto make_weak(std::shared_ptr<T> s) -> std::weak_ptr<T>
{
return { s };
}
然后將其稱為:
foo.Bar( make_weak(integer) );
因為你比編譯器更聰明,你必須幫助它推導出那個類型。
觀察這部分代碼。
template<typename R>
void Bar(std::weak_ptr<R> const & p)
您知道,對於可能存在的每個可能的R
,只有一個R
存在從std::shared_ptr<int>
的隱式轉換。 您可能沒有在其他地方編寫任何適用於此處的轉換運算符。
您的 C++ 編譯器不會知道或假設這一點。 所以你應該調用這個函數:
foo.Bar( std::weak_ptr<int>{integer} );
或者試試 Mark B 的回答中的方法。
您需要處理兩種(語言方面)完全不相關的類型,因此您需要提供兩種重載,一種用於每種指針類型。 然后 shared_ptr 版本可以通過在其調用中提供正確的T
來調用到 weak_ptr 版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.