decltype mit verschachtelten Funktionsaufrufen
-
Hallo zusammen,
ich frage ich mich, ob
man in folgendem Code das decltype von baz_type kürzen kann:#include <iostream> #include <tuple> int main() { auto foo = []{return 1;}; typedef decltype(foo()) foo_type; auto bar = [](const foo_type&){return 'c';}; typedef decltype(bar(foo())) bar_type; auto baz = [](const bar_type&){return 1.0;}; typedef decltype(baz(bar(foo()))) baz_type; auto quux = [](const baz_type&){}; }Muss man wirklich alle Funktionsaufrufe ineinanderschachteln oder kann ich das (mit Hilfe eines typedefs?) kürzen?
Gruß,
XSpille
-
Sieht jetzt vielleicht nicht kürzer aus, aber ist immerhin lineare statt quadratische Komplexität:
template<typename T> T creator(); int main() { //... typedef decltype(baz(creator<bar_type>())) baz_type; }
-
dafür gibt es std::declval. Mit std::declval<T>() kann man einen Ausdruck vom Typ T erzeugen zwecks Einsatz innerhalb von decltype. In welchem Header das definiert wird, weiß ich gerade nicht. Vielleicht <utility>? Es kann aber sein, dass Dein Compiler das noch nicht kennt.
Einen Ersatz kann man sich so bauen:
#include <type_traits> template<class T> typename std::add_rvalue_reference<T>::type declval();wobei aber die tatsächliche Verwendung außerhalb von nicht-evaluierten Ausdrücken einen Fehler darstellt. add_rvalue_reference wird hier eingesetzt, um unvollständige und abstrakte Typen als auch void zu unterstützen. Lvalues kann man aber auch damit erzeugen. Beispiel: declval<int&>() erzeugt ein Lvalue Ausdruck vom Typ int.
-
Danke euch beiden!

@krümelkacker:
Genau das habe ich gesucht. Mein Compiler (GCC 4.6.1) unterstützt es auch.Auch mit utility als Header lagst du richtig:
http://en.cppreference.com/w/cpp/utility/declval