Topic: Using decltype with multi-line statements?


Author: Jacob Liechty <jacob.liechty@gmail.com>
Date: Tue, 23 Mar 2010 03:43:31 CST
Raw View
Hello,

I'm inquiring as to whether there is a way to accomplish type
deduction for multi-line statements.  As an example:

// Here we have a function whose return type is dependent on the
parameter types
template<class T, class U>
some_type_trait<T, U>::type foo(T& t, U& u) { return do_something(t,
u); }

// And here we have a function that heavily manipulates an input
parameter before returning
template <class T>
auto my_function(T& t) -> decltype(?????)
{
  float b = 6;
  auto c = foo(t, b);
  auto d = foo(b, 7.0f);
  auto e = foo(d, d);
  auto f = foo(e, e);

  return f;
}

The problem is that decltype only works for an id-expression, and we
can't simply replace ????? with f, because f is not defined at that
scope.

Thanks

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Miles Bader <miles@gnu.org>
Date: Wed, 24 Mar 2010 05:51:51 CST
Raw View
Jacob Liechty <jacob.liechty@gmail.com> writes:
> The problem is that decltype only works for an id-expression, and we
> can't simply replace ????? with f, because f is not defined at that
> scope.

Why not just:

auto my_function(T& t) -> decltype(foo(foo(foo(t, 6.f),foo(t,
6.f)),foo(foo(t, 6.f),foo(t, 6.f))))

?

-Miles

--
Non-combatant, n. A dead Quaker.

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Jacob Liechty <jacob.liechty@gmail.com>
Date: Thu, 25 Mar 2010 18:09:22 CST
Raw View
> Why not just:
>
> auto my_function(T& t) -> decltype(foo(foo(foo(t, 6.f),foo(t,
> 6.f)),foo(foo(t, 6.f),foo(t, 6.f))))
>
> ?

I'm afraid that's really the only solution with the current standard.
It's a bit convoluted, not terribly maintainable, not terribly
"obvious," and may involve more complicated scenarios in which there
are implicit conversions to specified types, etc.

The problem I can still see with it also is if foo() differentiates
between r-values and l-values that are passed to it, returning a
different type for each (with the operator &&, this is actually a
pretty plausible scenario).

For example, this code is not well-formed:

template <class T, class U>
struct dummy
{
         ...
};

template<class T, class U>
dummy<T, U> foo(T&& t, U&& u)
{
 return dummy<T, U>();
}

auto my_function() -> decltype(foo(foo(1,2), 3))
{
 auto a = foo(1, 2);
 auto b = foo(a, 3);
 return b;
}

The decltype returns a dummy<dummy<int, int>, int> whereas my_function
itself returns a dummy<dummy<int, int>&, int>.

-Jacob

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Mathias Gaunard <loufoque@gmail.com>
Date: Thu, 25 Mar 2010 18:09:45 CST
Raw View
On 23 mar, 10:43, Jacob Liechty <jacob.liec...@gmail.com> wrote:
> Hello,
>
> I'm inquiring as to whether there is a way to accomplish type
> deduction for multi-line statements.

No. This would require to perform type inference and unification, and
no work has been done as to how to do that in C++.
This is why only single statement lambdas can have a deduced return
type.

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Fri, 26 Mar 2010 12:16:14 CST
Raw View
On Mar 26, 1:09 am, Mathias Gaunard <loufo...@gmail.com> wrote:
> On 23 mar, 10:43, Jacob Liechty <jacob.liec...@gmail.com> wrote:
>
> > I'm inquiring as to whether there is a way to accomplish type
> > deduction for multi-line statements.
>
> No. This would require to perform type inference and unification, and
> no work has been done as to how to do that in C++.
> This is why only single statement lambdas can have a deduced return
> type.

In fact there are two issues involved for a general case:
On the one side a lambda with more than one statement
could indeed rather simply deduce the return type if all
returns have the same type. This already works in gcc
and there is work in progress to *possibly* make that
part of the C++0x standard. The second - much harder -
issue would be to require that the compiler performs
automatic unification, if the types are different.

Returning to the OP's problem, I consider it as a really
bad style to abuse decltype for complex return type
deductions - it basically ends up in:

a) replicating the implementation in the decltype expression
b) leaking the implementation into the function declaration.

(b) is the worst one of it. I wonder when people complain
about (a): "Why do I have to duplicate my *implementation*:
Once in the function *declaration* and once in the function
body?" Maybe we should ask the committee to ensure that
defining the implementation in a function declaration should
be sufficient?   ;-)

Greetings from Bremen,

Daniel Kr   gler


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?ISO-8859-1?Q?Falk_Tannh=E4user?= <tannhauser86549spam@free.fr>
Date: Sat, 27 Mar 2010 12:42:08 CST
Raw View
Am 26.03.2010 19:16, schrieb Daniel Kr   gler:
> On Mar 26, 1:09 am, Mathias Gaunard<loufo...@gmail.com>  wrote:
>> On 23 mar, 10:43, Jacob Liechty<jacob.liec...@gmail.com>  wrote:
>>> I'm inquiring as to whether there is a way to accomplish type
>>> deduction for multi-line statements.
>> No. This would require to perform type inference and unification, and
>> no work has been done as to how to do that in C++.
>> This is why only single statement lambdas can have a deduced return
>> type.
> In fact there are two issues involved for a general case:
> On the one side a lambda with more than one statement
> could indeed rather simply deduce the return type if all
> returns have the same type. This already works in gcc
> and there is work in progress to *possibly* make that
> part of the C++0x standard. The second - much harder -
> issue would be to require that the compiler performs
> automatic unification, if the types are different.
>
> [...]  Maybe we should ask the committee to ensure that
> defining the implementation in a function declaration should
> be sufficient?   ;-)

While I'm not an expert in the field, it appears to me that the theoretical
bases for type inference and unification already
exist and are applied in some other languages as Haskell
<http://en.wikipedia.org/wiki/Type_inference>. However, the German
article <http://de.wikipedia.org/wiki/Typinferenz> states that type inference
collides with overloading, which could make it
difficult or even impossible to get it fully integrated into C++.

Falk


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Mathias Gaunard <loufoque@gmail.com>
Date: Mon, 29 Mar 2010 13:11:36 CST
Raw View
On 26 mar, 20:16, Daniel Kr   gler <daniel.krueg...@googlemail.com>
wrote:

>
> Returning to the OP's problem, I consider it as a really
> bad style to abuse decltype for complex return type
> deductions - it basically ends up in:
>
> a) replicating the implementation in the decltype expression
> b) leaking the implementation into the function declaration.

But for template functions, it has the nice side effect of masking the
function through SFINAE if the expression in decltype results in an
error after template substitution, providing the same behaviour as
concept-based overloading but with implicitly defined concepts.
It is required to duplicate the information because SFINAE only
applies to function declarations, which are separate from function
definitions (but you would have to duplicate that information with
concepts too, albeit only nominally).

There is a mechanism to infer the function declaration from the
function definition: lambdas. Unfortunately they cannot be
polymorphic, even if compilers will likely provide that as an
extension.



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: brangdon@cix.co.uk (Dave Harris)
Date: Mon, 29 Mar 2010 13:12:30 CST
Raw View
daniel.kruegler@googlemail.com (Daniel Kr   gler) wrote (abridged):
> In fact there are two issues involved for a general case:
> On the one side a lambda with more than one statement
> could indeed rather simply deduce the return type if all
> returns have the same type. This already works in gcc
> and there is work in progress to *possibly* make that
> part of the C++0x standard.

I hope they at least add support for lambdas with a single return. To me,
that:

   auto x = []() {
       return 1;
   }

compiles but:

   auto y = []() {
       printf( "here\n" );
       return 1;
   }

doesn't, seems like an arbitrary restriction, making the language
unnecessarily hard and complex. I don't see how the second version adds
any deep new unification problems.

-- Dave Harris, Nottingham, UK.

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]