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??
That’s a very interesting question. From my understanding, the first ‘WTF’ (the one with
typenamein the lambda body) should be the correct according to N3225 5.1.2/7 :As
Somethingis 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.