Reputation: 40859
Consider:
template < typename Something >
boost::function<void()> f()
{
typedef typename Something::what type;
return [](){};
}
In this code you need the typename because 'what' is a dependent name. But consider this:
template < typename Something >
boost::function<void()> f()
{
return []()
{
typedef typename Something::what type;
};
}
Compiler bitches: "typename cannot be used outside a template declaration"
WTF?
THIS works:
template < typename Something >
boost::function<void()> f()
{
return []()
{
typedef Something::what type;
};
}
What is it about the creation of a lambda that means "what" is not a dependent name anymore? Or is this just a bug?
Heh...correction. The latter doesn't work. It says that "Something" doesn't exist. This modified version DOES work though and still unintuitively doesn't need and won't accept "typename".
template < typename T > struct wtf { typedef typename T::what type; };
template < typename Something >
boost::function<void()> f()
{
return []() { typedef wtf<Something>::type type; };
}
Of course, now I have TWO questions: the original and, WTF doesn't it find "Something" unless it's used as a template parameter??
Upvotes: 4
Views: 868
Reputation: 76755
That's a very interesting question. From my understanding, the first 'WTF' (the one with typename
in the lambda body) should be the correct according to N3225 5.1.2/7 :
The lambda-expression’s compound-statement yields the function-body of the function call operator, but for purposes of name lookup, determining the type and value of this and transforming id-expressions referring to non-static class members into class member access expressions using (*this), the compound-statement is considered in the context of the lambda-expression.
As Something
is a dependent-name in the context of the lambda expression, it should also be a dependent name in the context of the lambda function body according to this quote.
Upvotes: 4
Reputation: 114695
It's because the lambda is actually a class defined by the compiler, it doesn't share the template arguments of the outer function, the lambda type is defined when the template is instantiated so the template argument is no longer dependant and typename
isn't needed.
Upvotes: 0