шаблоны, typename, lambda -> зависимые имена не зависимые? - PullRequest
3 голосов
/ 04 января 2011

Рассмотрим:

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

В этом коде вам нужно имя типа, потому что «что» является зависимым именем. Но учтите это:

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

Суки компилятора: "typename нельзя использовать вне объявления шаблона"

WTF?

ЭТО работает:

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

Что такое создание лямбды, что означает "что" больше не является зависимым именем? Или это просто ошибка?

Хех ... коррекция. Последний не работает. Он говорит, что «Нечто» не существует. Эта модифицированная версия работает, хотя и по-прежнему не нуждается в ней и не принимает "typename".

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

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

Конечно, теперь у меня есть ДВА вопроса: оригинал и WTF не находит "Нечто", если он не используется в качестве параметра шаблона ??

Ответы [ 2 ]

3 голосов
/ 04 января 2011

Это очень интересный вопрос.Насколько я понимаю, первый 'WTF' (тот, который имеет typename в теле лямбды) должен быть правильным в соответствии с N3225 5.1.2 / 7:

Лямбда-выражение * составной оператор дает тело-функции оператора вызова функции, , но для целей поиска по имени , определяя тип и значениеthis и преобразование id-выражений , ссылающихся на нестатические члены класса, в выражения доступа к членам класса с использованием (* this), составного оператора рассматривается в контексте лямбда-выражение .

Поскольку Something является зависимым именем в контексте лямбда-выражения, оно должно также бытьзависимое имя в контексте тела лямбда-функции согласно этой цитате.

0 голосов
/ 04 января 2011

Это потому, что лямбда на самом деле является классом, определенным компилятором, он не разделяет аргументы шаблона внешней функции, лямбда-тип определяется, когда создается экземпляр шаблона, поэтому аргумент шаблона больше не зависит и typename не требуется

...