簡體   English   中英

從 shared_ptr 推導出weak_ptr 參數

[英]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) );

使用 C++ 17 的類模板推導,這現在應該是合法的:

auto shared = std::make_shared< int >( 3 );
auto weak = std::weak_ptr( shared );
std::weak_ptr weak2( shared );

coliru上看到它。

因為你比編譯器更聰明,你必須幫助它推導出那個類型。

觀察這部分代碼。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM