2016-03-03 56 views
3

我其中我试图传递的unique_ptr的底层指针中,以接受一个指针通过引用的方法的代码:的unique_ptr和指针通过引用参数类型

unique_ptr<A> a; 

func(a.get()); 

调用:

void func(A*& a){ // I am modifying what `a` points to in here 

} 

但我得到编译器错误,因为get()没有返回我所期望的只是原始指针。是否有可能实现我在这里要做的事情?

+0

你为什么要这么做? – Holt

+0

如果你只想修改'a'指向的内容而不是智能指针,那么你应该接受一个*原始指针*作为参数,而不是*原始指针引用*:'void func(A * a);':这个链接是关于'shared_ptr',但同样的逻辑适用:https://stackoverflow.com/questions/35543520/how-to-pass-shared-ptr-to-class-with-lower-lifetime/35543963#35543963 – Galik

回答

11

不,这是件好事。

问题是,get()返回一个右值,而不是对unique_ptr的内部指针的引用。所以你不能修改它。如果可以的话,你会完全搞砸unique_ptr的内部状态。

只要通过对unique_ptr本身的引用,如果您想修改它即可。

3

通过引用接受指针的函数强烈暗示它可能会重新分配/删除有问题的指针。这意味着它要求所有权责任。调用这种函数的唯一安全方法是从该唯一指针释放指针,并且(可能)在调用之后重新获取它。

// a currently manages (owns) the pointer 
std::unique_ptr<A> a; 

// release ownership of internal raw pointer 
auto raw = a.release(); 

// call function (possibly modifying raw) 
func(raw); 

// (re)claim ownership of whatever func() returns 
a.reset(raw); 

但是,这仍然是有问题的,如果(说)的unique_ptr具有特殊缺失者和函数没有相应的重新分配的对象。另外,如果功能删除指针而未将其设置为nullptr,则会出现问题。

2

这里有一个想法:

template<typename T> struct raw_from_ptr { 
    raw_from_ptr(T& pointer) : _pointer(pointer), _raw_pointer(null_ptr) {} 
    ~raw_from_ptr() { 
     if (_raw_pointer != null_ptr) 
      _pointer.reset(_raw_pointer); 
    } 
    raw_from_ptr(pointer_wrapper&& _other) : _pointer(_other._pointer) { 
     std::swap(_raw_pointer, _other._raw_pointer); 
    } 
    operator typename T::pointer*() && { return &_raw_pointer; } 
    operator typename T::pointer&() && { return _raw_pointer; } 

private: 
    T& _pointer; 
    typename T::pointer _raw_pointer; 
}; 

template<typename T> raw_from_ptr<T> get_raw_from_ptr(T& _pointer) { 
    return raw_from_ptr<T>(_pointer); 
} 

用法:

unique_ptr<A> a; 
func(get_raw_from_ptr(a));