From 77c32269486a0568c2168693ce68c1537c42d7d7 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 27 Nov 2017 02:07:04 +0100 Subject: [PATCH] TreeExplorer: identify yet another subtle type inference problem surprising behaviour encountered while covering more cases ...obviously the return type of ExpandFunctor::operator() was inferred as value, even while the invoked functor, from which this type was deduced, clearly returns a reference. Solution is simple not to rely on inference, moreover since we know the exact type in the enclosing scope, thanks to the refactoring which made this ExpandFunctor a nested class NOTE: as it turned out, this is not a compiler bug, but works as defined by the language: on return type inference, the detected type is decayed, which usually helps to prevent returning a reference to a temporary --- doc/technical/code/c++11.txt | 24 ++++++++++++++++++++++++ src/lib/iter-tree-explorer.hpp | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/doc/technical/code/c++11.txt b/doc/technical/code/c++11.txt index e504b51c4..26fd7eda4 100644 --- a/doc/technical/code/c++11.txt +++ b/doc/technical/code/c++11.txt @@ -221,3 +221,27 @@ Thus -- as of 9/2014 -- the _rules of the game_ are as folows to variadic templates and `std::tuple` + +Type inference +~~~~~~~~~~~~~~ +Generally speaking, the use of `auto` and type inference has the potential to significantly improve readability of +the code. Indeed, this new language feature is what removed most of the clumsiness regarding use of the Lumiera +Forward Iterator concept. There are some notable pitfalls to consider, though + +- the `decltype(...)` operator is kind-of ``overloaded'', insofar it supports two distinct usages + + * to find out the type of a given _name_ + * to deduce the type of a given _expression_ + +- and the `auto` type inference does not just pick up what `decltype` would see -- rather, it applies its own + preferences and transformations (which does make much sense from a pragmatic perspective) + + * a definition with `auto` type specification always prefers to create an object or data element. This is very much + in contrast to the usual behaviour of the C++ language, which by default prefers a reference as result type of + expression evaluation. + * return type deduction always _decays_ the inferred type (similar as `std::decay::type` does). Which means, + functions and arrays become pointers, and a _reference_ becomes a _value_. Given the danger of returning a + dangling reference to local storage, the latter is a sensible default, but certainly not what you'd expect + when just passing the result from a delegate function (or lambda!). + + diff --git a/src/lib/iter-tree-explorer.hpp b/src/lib/iter-tree-explorer.hpp index 0493b9792..665b291e5 100644 --- a/src/lib/iter-tree-explorer.hpp +++ b/src/lib/iter-tree-explorer.hpp @@ -364,7 +364,7 @@ namespace lib { function expandFun; template - auto + Res operator() (ARG& arg) { auto accessArg = ArgAccessor::build();