Topic: templates, lambda, and dependent names


Author: Noah Roberts <noneed@toemailme.com>
Date: Wed, 5 Jan 2011 13:33:09 CST
Raw View
I've run into something I did not expect when trying to create a lambda
function within a templated function, namely dependent names are not
behaving as I would expect.  I'm trying to find out if I'm working with
a bad implementation or if my intuition and experience fail in this
case.

template < typename T >
function<void()> f()
{
   return []() { typedef typename T::type type; };
}

This one fails for two reasons: 1) the compiler insists that typename is
invalid here and 2) it doesn't see the T symbol.  Taking the typename
out gets rid of the first error.

template < typename T >
struct get_type { typedef typename T::type type; };

template < typename T >
function<void()> f()
{
   return [](){ typedef typename get_type<T>::type type; };
}

This one only fails because the compiler insists that typename can't be
used here.  Getting rid of that and the program compiles and works
correctly.

My original code uses boost's function, but afaict that wouldn't make
any difference.

I've tried various other places before coming here.  Everyone is
guessing though.  Best reply so far is this one:
http://stackoverflow.com/questions/4589056/templates-typename-lambda-
dependent-names-not-dependent/4593286#4593286

I'm looking for something definitive though.  Is "icecrime's" answer
correct?

The compiler is MSVC2010 but I'm looking for what the standard specifies
here.

Thanks.

--
http://crazyeddiecpp.blogspot.com/


[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Inconnu <shirarenai@yandex.ru>
Date: Sat, 8 Jan 2011 19:40:36 CST
Raw View
On 5       , 22:33, Noah Roberts <non...@toemailme.com> wrote:
> I've run into something I did not expect when trying to create a lambda
> function within a templated function, namely dependent names are not
> behaving as I would expect.  I'm trying to find out if I'm working with
> a bad implementation or if my intuition and experience fail in this
> case.
>
> template < typename T >
> function<void()> f()
> {
>    return []() { typedef typename T::type type; };
>
> }
>
> This one fails for two reasons: 1) the compiler insists that typename is
> invalid here and 2) it doesn't see the T symbol.  Taking the typename
> out gets rid of the first error.
>
> template < typename T >
> struct get_type { typedef typename T::type type; };
>
> template < typename T >
> function<void()> f()
> {
>    return [](){ typedef typename get_type<T>::type type; };
>
> }
>
> This one only fails because the compiler insists that typename can't be
> used here.  Getting rid of that and the program compiles and works
> correctly.
>
> My original code uses boost's function, but afaict that wouldn't make
> any difference.
>
> I've tried various other places before coming here.  Everyone is
> guessing though.  Best reply so far is this one:http://stackoverflow.com/questions/4589056/templates-typename-lambda-
> dependent-names-not-dependent/4593286#4593286
>
> I'm looking for something definitive though.  Is "icecrime's" answer
> correct?
>
> The compiler is MSVC2010 but I'm looking for what the standard specifies
> here.
>
> Thanks.
>

Yes, "icecrime's" answer is correct, "Motti's" answer is wrong. The
standard though, as far as I understand, doesn't permit now an
implicit conversion from lambda expression to function<...> or any
other user-written class. And, as far as MSVC is concerned, it looks
very much like that it doesn't parse template function bodies at all,
it parses them during instantiation, substituting template parameters
with their values, that's why it isn't strange that 'typenames' only
hamper it to work.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Joe Gottman <josephgottman@comcast.net>
Date: Sun, 9 Jan 2011 10:38:05 CST
Raw View
On 1/8/2011 8:40 PM, Inconnu wrote:
>
> On 5       , 22:33, Noah Roberts<non...@toemailme.com>  wrote:
>> I've run into something I did not expect when trying to create a lambda
>> function within a templated function, namely dependent names are not
>> behaving as I would expect.  I'm trying to find out if I'm working with
>> a bad implementation or if my intuition and experience fail in this
>> case.
>>
>> template<  typename T>
>> function<void()>  f()
>> {
>>     return []() { typedef typename T::type type; };
>>
>> }
>>
>> This one fails for two reasons: 1) the compiler insists that typename is
>> invalid here and 2) it doesn't see the T symbol.  Taking the typename
>> out gets rid of the first error.
>>
>> template<  typename T>
>> struct get_type { typedef typename T::type type; };
>>
>> template<  typename T>
>> function<void()>  f()
>> {
>>     return [](){ typedef typename get_type<T>::type type; };
>>
>> }
>>
>> This one only fails because the compiler insists that typename can't be
>> used here.  Getting rid of that and the program compiles and works
>> correctly.
>>
>> My original code uses boost's function, but afaict that wouldn't make
>> any difference.
>>
>> I've tried various other places before coming here.  Everyone is
>> guessing though.  Best reply so far is this one:http://stackoverflow.com/questions/4589056/templates-typename-lambda-
>> dependent-names-not-dependent/4593286#4593286
>>
>> I'm looking for something definitive though.  Is "icecrime's" answer
>> correct?
>>
>> The compiler is MSVC2010 but I'm looking for what the standard specifies
>> here.
>>
>> Thanks.
>>
>
> Yes, "icecrime's" answer is correct, "Motti's" answer is wrong. The
> standard though, as far as I understand, doesn't permit now an
> implicit conversion from lambda expression to function<...>  or any
> other user-written class. And, as far as MSVC is concerned, it looks
> very much like that it doesn't parse template function bodies at all,
> it parses them during instantiation, substituting template parameters
> with their values, that's why it isn't strange that 'typenames' only
> hamper it to work.

Actually, I think it does.  std::function has the non-explicit constructor
 template<class F> function(F f)

I'm pretty sure that if the parameter types and return types of the
lambda function match those of the function template that implicit
conversion will occur.

Joe Gottman


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]