Template instantiation, two-phase name lookup, different behavior with automatic deduced type

瘦欲@ 提交于 2019-12-23 09:19:49

问题


After seeing this question When is a C++ template instantiation type checked? , and wondering myself for quite some time the same thing I started to play with code to assimilate the knowledge. The answer gives clear and correct explanation. It mentions two-phase name lookup and the fact that the end of translation unit is also considered a point of instantiation for function templates. However I observed different behavior when using automatic return type deduction:

This is like the original code. It is correct and works as explained in the linked post:

class A;
class B;

template <class T> auto foo() -> T * {
  A *pa = nullptr; // ignore pa being `nullptr`.
  return static_cast<T *>(pa);
}

auto test() { return foo<B>(); }

class A {};
class B : public A {};

When using automatic return type deduction for the template foo, the definitions of A and B must appear before the instantiation point of foo:

Not working:

class A;
class B;

template <class T> auto foo()  { // automatic return type deduction
  A *pa = nullptr;
  return static_cast<T *>(pa);
}

auto test() { return foo<B>(); }

class A {};
class B : public A {};

The error by gcc (4.9 and 5.2.1):

error: invalid static_cast from type ‘A*’ to type ‘B*’

Clang gives a similar error

Working:

class A;
class B;

template <class T> auto foo()  { // automatic return type deduction
  A *pa = nullptr;
  return static_cast<T *>(pa);
}

class A {};
class B : public A {};

auto test() { return foo<B>(); }

Why it is happening? Why is that the rule about the end of compilation unit beeing considered a point of instantiation doesn't make the template instantiation legitimate anymore?

来源:https://stackoverflow.com/questions/34207433/template-instantiation-two-phase-name-lookup-different-behavior-with-automatic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!