Не зависящий поиск имени и лямбда

У меня есть следующий код:

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.