Próbuję skompilować następujący kod (nieco minimalny przykład), złożyć test.cpp
:dzyń: nie można rzutować do prywatnej bazy natomiast jest public virtual dziedziczenie
#include <iostream>
#include <memory>
class Shared : public std::enable_shared_from_this<Shared>{
public:
int prea;
};
class Widget : public virtual Shared{
int a;
public:
~Widget(){
a = 7;
}
};
class Container : virtual public Widget{
};
class List : private Container, virtual public Widget{
public:
int c;
};
int main(int argc, char** argv){
auto c = std::make_shared<List>();
c->c = 3;
std::cout << c->c << std::endl;
return 0;
}
Korzystanie clang++
następująco:
clang++ test.cpp -std=c++11
I to daje mi następujący błąd:
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/shared_ptr_base.h:1106:50: error:
cannot cast 'List' to its private base class 'const enable_shared_from_this<Shared>'
__enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
^
Zobacz pełne wyjście here.
Następnie, jeśli skompiluję ten sam kod przy użyciu g ++, nie wystąpi błąd i zostanie wygenerowany plik wykonywalny. Powiedziałbym, że jest to wynik, jakiego oczekuję. Nie mam pojęcia dlaczego clang ++ nie lubi kodu.
Pytanie brzmi, kto ma rację? clang++
lub g++
?
Edit: może być powielana nawet na mniejszych przykład:
#include <iostream>
#include <memory>
struct Shared : public std::enable_shared_from_this<Shared>{
};
struct Container : virtual public Shared{
};
struct List : private Container, virtual public Shared {
};
int main(int argc, char** argv){
auto c = std::make_shared<List>();
return 0;
}
Jestem ciekawa, czy możesz skompilować to ze standardową biblioteką klang? Jak widać, domyślnie clang w systemach * nix używa standardowej biblioteki gcc. Może to błąd, zwłaszcza gdy clang kompiluje standardowy kod biblioteki gcc. Edycja: Szybko przetestowałem to na coliru, wygląda na to, że standardowa biblioteka nie robi różnicy, ale OP może powinieneś to zweryfikować. –
Znacznie mniejszy przypadek repro (rozważ aktualizowanie pytania): http://coliru.stacked-crooked.com/a/56d44d6bf2ce459b –
Działa, jeśli używasz 'Listy klas: wirtualny widget publiczny, prywatny kontener '. – skypjack