Reputation: 171
I have the following code:
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;
}
As you can see, there is a template class that contains a nested class, which in constructor calls some template method of its enclosing class. AFAIK, even though enclosing class is a template class - for the nested class it is a non-dependent name, so calling its template method without template
should not be a problem. The problem happens when I define a lambda inside nested class' constructor, capture pointer to outer class, and try to call the same template method - g++7.2 gives the following compilation error:
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'
However, g++-5.4 and g++-6.3 compile this code just fine. So it seems that g++-7.2 treats the outer_ptr
's type inside the lambda as a dependent name - and I cannot understand why. Can someone explain this to me?
Upvotes: 16
Views: 417
Reputation: 304122
Yes, this is a gcc regression. Filed as 82980.
Here's a reduced example:
template <class T>
struct Outer
{
template <class U>
void f();
void bar(Outer outer) {
[outer](){ outer.f<int>(); };
}
};
int main() { }
outer.f
is member access for the current instantiation, so that expression shouldn't count as type dependent, so you shouldn't need to provide the template
keyword.
Upvotes: 2