CRTP- und c ++ 1y-Rückgabetyp-Abzug
Ich habe kürzlich mit CRTP gespielt, als ich auf etwas gestoßen bin, das mich bei der Verwendung mit c ++ 1y-Funktionen überrascht hat, deren Typ abgeleitet wurde. Der folgende Code funktioniert:
template<typename Derived>
struct Base
{
auto foo()
{
return static_cast<Derived*>(this)->foo_impl();
}
};
struct Derived:
public Base<Derived>
{
auto foo_impl()
-> int
{
return 0;
}
};
int main()
{
Derived b;
int i = b.foo();
(void)i;
}
Ich nahm an, dass der Rückgabetyp vonBase<Derived>::foo
war eindecltype
des Ausdrucks zurückgegeben, aber wenn ich die Funktion änderefoo
so was:
auto foo()
-> decltype(static_cast<Derived*>(this)->foo_impl())
{
return static_cast<Derived*>(this)->foo_impl();
}
Dieser Code funktioniert nicht mehr, ich erhalte folgende Fehlermeldung (ab GCC 4.8.1):
||In instantiation of 'struct Base<Derived>':|
|required from here|
|error: invalid static_cast from type 'Base<Derived>* const' to type 'Derived*'|
||In function 'int main()':|
|error: 'struct Derived' has no member named 'foo'|
Meine Fragen sind: Warum funktioniert es nicht? Was könnte ich schreiben, um den richtigen Rückgabetyp zu erhalten, ohne auf den automatischen Abzug des Rückgabetyps angewiesen zu sein?
Und nun ... hier ist einLive-Beispiel.