rozważyć poniższą kod:Pośrednie konwersji z int do shared_ptr
#include <iostream>
#include <memory>
void f(std::shared_ptr<int> sp) {}
template <typename FuncType, typename PtrType>
auto call_f(FuncType f, PtrType p) -> decltype(f(p))
{
return f(p);
}
int main()
{
f(0); // doesn't work for any other int != 0, thanks @Rupesh
// call_f(f, 0); // error, cannot convert int to shared_ptr
}
W pierwszym wierszu w main()
liczba całkowita 0
przekształca się w std::shared_ptr<int>
a połączenie f(0)
udaje się bez problemu. Jednak użycie szablonu do wywołania funkcji powoduje, że rzeczy się różnią. Druga linia nie będzie już skompilować, błąd jest
error: could not convert 'p' from 'int' to 'std::shared_ptr<int>'
moje pytania są:
- Dlaczego pierwsze połączenie uda, a druga nie? Czy jest tu coś, czego mi tu brakuje?
- Nie rozumiem też, jak konwersja z
int
dostd::shared_ptr
jest wykonywana w zaproszeniuf(0)
, jak to wyglądastd::shared_ptr
ma tylko jawnych konstruktorów.
PS: Wariant tym przykładzie pojawia się Scott Meyers' skutecznych, nowoczesnych C++ punktu 8, jako sposób ochrony tych połączeń z nullptr
.
@@ vsoftco należy wspomnieć, że to działa tylko dla 'f (0)', oprócz zera nic nie jest kompilacji samego błędu dla innych wartości nawet w pierwszym wywołaniu. –
[This] (http://en.cppreference.com/w/cpp/language/nullptr) sugeruje wyjaśnienie - "Istnieją niejawne konwersje z nullptr na wartość wskaźnika zerowego dowolnego typu wskaźnika i dowolnego wskaźnika na typ pręta. Podobne konwersje istnieją dla dowolnej wartości typu std :: nullptr_t oraz dla makra NULL, stała wskaźnika zerowego. " Interesujące byłoby jednak, aby wyjaśnić to standardowymi odniesieniami i większą jasnością. – Pradhan
@RupeshYadav. Gotowe. Rzeczywiście, jest to bardzo dziwne, wygląda na to, że wykonywana jest jakaś niejawna konwersja wskaźnika. – vsoftco