Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

templates, typename, lambda -> dependent names not dependent?

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??

like image 688
Edward Strange Avatar asked Sep 20 '25 05:09

Edward Strange


1 Answers

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.

like image 92
icecrime Avatar answered Sep 21 '25 21:09

icecrime