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
This commit is contained in:
parent
6667a51a61
commit
77c3226948
2 changed files with 25 additions and 1 deletions
|
|
@ -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<T>::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!).
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ namespace lib {
|
|||
function<Sig> expandFun;
|
||||
|
||||
template<typename ARG>
|
||||
auto
|
||||
Res
|
||||
operator() (ARG& arg)
|
||||
{
|
||||
auto accessArg = ArgAccessor<ARG>::build();
|
||||
|
|
|
|||
Loading…
Reference in a new issue