Rozważmy następujący:Dlaczego funkcja automatycznego zwracania działa z nie w pełni zdefiniowanymi typami?
template<typename Der>
struct Base {
// NOTE: if I replace the decltype(...) below with auto, code compiles
decltype(&Der::operator()) getCallOperator() const {
return &Der::operator();
}
};
struct Foo : Base<Foo> {
double operator()(int, int) const {
return 0.0;
}
};
int main() {
Foo f;
auto callOp = f.getCallOperator();
}
Chcę utworzyć funkcję składową klasy bazowej CRTP z rodzajem powrotu w zależności od podpisania operator()
w klasie pochodnej. Jednak decltype(&Der::operator())
nie kompiluje się; Funkcja członkowska operator()
w Foo
nie jest widoczna. Zakładam, że dzieje się tak, ponieważ szablon klasy podstawowej jest tworzony przed pełną definicją Foo
.
Co zaskakujące, jeśli wstawię auto
dla typu zwracanego, kompiluje się. Zakładam, że auto
spowodowałoby, że kompilator wywnioskuje typ zwracany z treści funkcji i nie powiedzie się - ponieważ ciało używa nie zdefiniowanego w pełni typu: Foo
.
Takie zachowanie jest taka sama zarówno dla MSVC 2015.3 i Clang 3.8
Dlaczego kod zacząć pracować z auto
? Czy odliczenie typu auto
w jakiś sposób "opóźnia" tworzenie instancji? Lub użyć innego kontekstu niż ręcznie napisane wyrażenie typu zwrotu?
Dobre pytanie. Rewizja. –
Prawdopodobny duplikat odliczenia zwrotnego zwrotu CRTP i C++ 1y (http://stackoverflow.com/questions/19892479/crtp-and-c1y-return-type-deduction) – Holt
Jest to ten sam problem, ale pytanie i odpowiedź to z nieco innego kąta. Tutaj mamy "w jaki sposób dedukcja automatyczna jest inna", powiązane pytanie i jego odpowiedź dotyczą raczej "w jaki sposób mogę wykonać ręczną pracę ekspresywną". Choć może nadal kwalifikować się jako duplikat ... –