Ich habe vor kurzem herausgefunden, dass declltype Ausdrücke als Teil der Funktionen Symbolnamen verstümmelt sind, wenn sie als Rückgabetypen verwendet werden, und dies kann die Ursache für böse Segmentierungsfehler beim Entmelden der Ausdrücke sein (in Debugging-Sitzungen zum Beispiel), wenn Ausdruck ist zu komplex.Warum Deklinationsausdrücke in Rückgabetypen müssen im Symbolnamen manipuliert werden?
Die erste Version, in der Funktion Rückgabetyp mit decltype, wo der volle Ausdruck (http://goo.gl/EALubx) verstümmelt wird:
#include <cstdint>
#include <utility>
struct A { void bar() const; };
template<typename T>
decltype(std::declval<T>().bar()) foo(T const& a);
void foo() { A a; return foo(a); }
auf (GCC 5.2.0) zusammengestellt:
foo():
sub rsp, 24
lea rdi, [rsp+15]
call decltype ((((declval<A>)()).bar)()) foo<A>(A const&)
add rsp, 24
ret
Die zweite Version, fast gleichwertig, wobei der Ausdruckstyp als Teil eines zusätzlichen Vorlagenparameters aufgelöst wird (http://goo.gl/DfQGR5):
#include <cstdint>
#include <utility>
struct A { void bar() const; };
template<typename T, typename R=decltype(std::declval<T>().bar())>
R foo(T const& a);
void foo() { A a; return foo(a); }
auf (GCC 5.2.0) zusammengestellt:
foo():
sub rsp, 24
lea rdi, [rsp+15]
call void foo<A, void>(A const&)
add rsp, 24
ret
Ich verstehe, dass nur bei ihrer Rückkehr Art Template-Funktionen überlastet werden können, soll aber nicht der Compiler der Lage sein, den decltype Ausdruck auf seinem eigenen zu lösen und mangle stattdessen den resultierenden Typ?
Kann mir jemand sagen warum, oder zeigen Sie mir, wo in der C++ - Spezifikation angegeben ist?
Ich sehe nichts falsch daran, es ist nur der Name der Funktion. Eigentlich wäre ein aufgelöster Rückgabetyp sehr viel verwirrender ... –
Ich glaube, dass die Unterstützung von willkürlichen komplexen Ausdrücken in verfälschten Namen nicht trivial ist und der Implementierung des Umsetzers höhere Einschränkungen auferlegt. Während ich zustimme, dass es ein Implementierungsproblem ist, zum Beispiel, GDB segfaults, wenn die Ausdrücke zu komplex sind. –
Nun, der Compiler * könnte auch die aufgelöste Information ausgeben und anderen Tools in der Kette helfen. Mein Rat, sei * extrem * geduldig ... (https://sourceware.org/bugzilla/show_bug.cgi?id=14441) –