从shared_ptr中减去weak_ptr参数

时间:2015-04-14 17:11:59

标签: c++ shared-ptr weak-ptr

以下给出了编译器错误:

  

无法推断出' const std :: weak_ptr< _Ty>的模板参数&安培;'   来自' std :: shared_ptr'

#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);
}

要明确我要明确说明函数应该采用共享或弱_ptr,所以我不喜欢R const&amp;解决方案。

为了完整性,这当然也有效:

template<typename R>
void Bar(std::shared_ptr<R> const & p)
{
    auto w = std::weak_ptr<R>(p);
}

4 个答案:

答案 0 :(得分:3)

R的模板参数std::weak<R>无法从std::shared_ptr<A>的实例中推断出来,因为转换构造函数(需要std::shared_ptr<Y>)是构造函数模板,这意味着{ {1}}可以是任何内容 - 并且无法从Y推断R(推断为Y)。看看转换构造函数。

你可以这样写:

A

然后将其称为:

template<typename T>
auto make_weak(std::shared_ptr<T> s) ->  std::weak_ptr<T>
{
  return { s };
}

答案 1 :(得分:1)

因为你比编译器更聪明,所以你必须帮助它推断出那种类型。

观察代码的这一部分。

template<typename R>
void Bar(std::weak_ptr<R> const & p)

知道,对于可能存在的每个可能R只有一个R ,其隐含的转化来自{ {1}}。您可能没有在其他地方编写任何适用于此处的转换运算符。

您的C ++编译器不知道或假设这一点。所以你应该把这个函数称为:

std::shared_ptr<int>

或者尝试Mark B的答案中的方法。

答案 2 :(得分:1)

您需要处理两个(语言方面)完全不相关的类型,因此您需要提供两个重载,每个指针类型一个。然后,shared_ptr版本可以通过在其调用中提供正确的T来调用weak_ptr版本。

答案 3 :(得分:0)

使用C ++ 17&#39; class template deduction,现在这应该是合法的:

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

我无法测试它。