Hi,
TL;DR
If you're passing a scoped_refptr to base::Bind, and the bound function expects a raw non-owning pointer, then you will need to wrap the scoped_refptr in base::RetainedRef.
void DoStuff(Foo* foo) {}
scoped_refptr<Foo> foo;
base::Bind(&DoStuff, foo); // ERROR!
base::Bind(&DoStuff, base::RetainedRef(foo)); // OK
Details
As we starting working towards making scoped_refptr constructor explicit (crbug.com/589048), we found that a large portion of implicit scoped_refptr construction was happening in base::Bind.
That is, base::Bind would always unwrap scoped_refptrs into the underlying raw pointer and pass that to the bound function. However, if the bound function expected a scoped_refptr, then one would be created implicitly.
In order to avoid this, base::Bind will no longer unwrap scoped_refptrs (as of https://codereview.chromium.org/1816713002/). The only case where this breaks existing code is when a scoped_refptr was being passed, but the function expected a raw non-owning pointer.
Enter base::RetainedRef. This retains a reference to the passed pointer (much like scoped_refptr would). The only difference is that this pointer will be unwrapped and passed as a raw pointer to the bound function.
To summarize in code,
void WantsScopedRefptr(scoped_refptr<Foo> foo) {}
void WantsRawPointer(Foo* foo) {}
scoped_refptr<Foo> refptr;
Foo* rawptr;
// OK: passed scoped_refptr, expects scoped_refptr
base::Bind(&WantsScopedRefptr, refptr);
// ERROR: passing a raw pointer of a ref counted object.
base::Bind(&WantsScopedRefptr, rawptr);
// ERROR: Can't convert refptr to a raw pointer.
base::Bind(&WantsRawPointer, refptr);
// OK: refptr will be unwrapped
base::Bind(&WantsRawPointer, base::RetainedRef(refptr));
Thanks,
Vlad