Smart pointer z typem, który jest zadeklarowany ale nie zdefiniowany
Ostatnio zmodyfikowano 2022-08-17 22:14
pekfos |
» 2022-08-17 06:58:48 Wtedy natrafiłem na wpis blogowy: https://ortogonal.github.io/cpp/forward-declaration-and-smart-pointers/, który pokazuje ten trick, że zdefiniowanie destruktora w innej jednostce translacji magiczne pozwala na stworzenie smart-pointera z forward zadeklarowanego typu, bez definicji. Autor wyjaśnia nawet dlaczego to działa. Dlaczego od razu magicznie, skoro jest wyjaśnione? Przy czym to nie jest dokładnie ten sam problem. Zainkluduj w main.cpp Helper zamiast Number i znowu się nie kompiluje. Póki mówimy o kompilacji, podział na pliki tylko zaciemnia sprawę. Teraz masz taki kod: #include <memory>
struct Number;
struct Helper { Helper() { } ~Helper(); std::unique_ptr < Number > ptr; };
struct Number { }; Można to uprościć do czegoś takiego: struct Foo;
template < class T > void f() { sizeof( T ); }
int main() { f < Foo >(); }
Kod zaczyna się kompilować po odkomentowaniu definicji, która intuicyjnie nie powinna niczego naprawiać, bo jest po wywołaniu które wymaga kompletnego typu. To działa dlatego że kompilator może przenieść point of instantiation na koniec jednostki translacji, gdzie w tym wypadku typ jest już znany w całości. https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#993https://eel.is/c++draft/temp.res#temp.point-7A tutaj przykład z "prawdziwego" projektu, gdzie występuje ten "problem": To nie jest argument że do prawdziwego projektu da się wprowadzić taki problem. Jeśli kod nie był pisany z myślą o użyciu smart pointera, to czemu miałoby się dać go trywialnie dodać? Rozwiązanie z githuba wygląda podejrzanie, być może unique_ptr<> nie jest tu poprawne. |
|
Kyriet Temat założony przez niniejszego użytkownika |
» 2022-08-17 22:14:00 Ciekawy jest ten Twój uproszczony przykład. Myślę, że możliwość przeniesienia point of instantiation na koniec jednostki translacji to był ten brakujący puzzel, który był mi potrzebny do zrozumienia co tutaj się właściwie dzieje. Nadal muszę to jeszcze przetrawić 😄
Dziękuję za wszystkie odpowiedzi! |
|
1 « 2 » |