Не зависящий поиск имени и лямбда
У меня есть следующий код:
template <class T>
class Outer
{
public:
Outer();
template <class U>
void templateFunc()
{
}
private:
class Inner
{
public:
Inner(Outer& outer)
{
outer.templateFunc<int>();
Outer* outer_ptr = &outer;
[outer_ptr]()
{
outer_ptr->templateFunc<int>();
}();
}
};
Inner m_inner;
};
template <class T>
Outer<T>::Outer()
: m_inner(*this)
{
}
int main()
{
Outer<double> outer;
}
Как вы можете видеть, существует класс шаблона, который содержит вложенный класс, который в конструкторе вызывает некоторый шаблонный метод его охватывающего класса. AFAIK, хотя охватывающий класс является классом шаблона - для вложенного класса это не зависящее имя, поэтому вызов его метода шаблона без template
не должен быть проблемой. Проблема возникает, когда я определяю лямбда внутри конструктора вложенного класса, убираю указатель на внешний класс и пытаюсь вызвать тот же метод шаблона - g++ 7.2 дает следующую ошибку компиляции:
prog.cc: In lambda function:
prog.cc:22:41: error: expected primary-expression before 'int'
outer_ptr->templateFunc<int>();
^~~
prog.cc:22:41: error: expected ';' before 'int'
Однако g++ - 5.4 и g++ - 6.3 компилируют этот код просто отлично. Похоже, что g++ - 7.2 рассматривает тип outer_ptr
внутри лямбда как зависимое имя - и я не могу понять, почему. Может кто-нибудь объяснить это мне?
Ответы
Ответ 1
Да, это регрессия gcc. Подано как 82980.
Здесь приведен пример:
template <class T>
struct Outer
{
template <class U>
void f();
void bar(Outer outer) {
[outer](){ outer.f<int>(); };
}
};
int main() { }
outer.f
- это членский доступ для текущего экземпляра, поэтому выражение не должно считаться зависит от типа, поэтому вам не нужно указывать ключевое слово template
.