非依赖名称查找和lambda

时间:2017-11-13 09:58:01

标签: c++ c++11 templates lambda language-lawyer

我有以下代码:

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的模板方法应该不是问题。当我在嵌套类中定义一个lambda时会出现问题。构造函数,捕获指向外部类的指针,并尝试调用相同的模板方法 - 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将lambda中的outer_ptr类型视为依赖名称 - 我无法理解为什么。有人可以向我解释一下吗?

1 个答案:

答案 0 :(得分:2)

是的,这是一个gcc回归。归档为82980

这是一个简化的例子:

template <class T>
struct Outer
{
    template <class U>
    void f();

    void bar(Outer outer) {
        [outer](){ outer.f<int>(); };
    }
};

int main() { }

outer.fcurrent instantiation的成员访问权限,因此该表达式不应计为type dependent,因此您不需要提供template }关键字。