Certain errors in uninstantiated template not repo

2020-02-07 00:02发布

Consider this example:

class A
{
  void foo();
  public:
  void bar();
};

template <class> class B
{
  B()
  {
    A a;
    a.foo();    // 1
    A::bar();   // 2
    a.bar(1);   // 3
  }
};

Note B is never instantiated.

clang++ reports all three marked lines as erroneous. g++ (4.8.3) accepts lines 1 and 2 and only reports line 3.

If B is instantiated, g++ happily reports all three lines as erroneous.

Is this a g++ bug? One would think so. A is not a dependent name and its members should be checked normally at template definition time. Are there nuances I don't see?

2条回答
看我几分像从前
2楼-- · 2020-02-07 00:34

It's not possible in general to tell whether a.foo(); or A::bar(); are an error at template definition time, even for those specific definitions of A::foo and A::bar.

Generally speaking, a.foo(); could be valid if A had some specialisations of B<T> as a friend, but not others, which would make the validity dependent on the template argument.

Generally speaking, A::bar(); could be valid if B<T> had A as a base class, directly or indirectly, and template classes do not generally know their base class yet at template definition time.

Even though it's possible to detect that neither of these is possible here (A has no friends, and B<T> has no base), it requires significant effort for little benefit. Because of this, it makes sense to simply always perform such checks at instantiation time, and that's the approach GCC has taken.

There is actually no rule in C++ that requires this to be diagnosed at template definition time (as Marco A.'s answer rightly points out). It's only when a template is instantiated that any errors in the template definition render the program ill-formed with a requirement for a diagnostic, per 2.2p1 bullet point 8:

The program is ill-formed if any instantiation fails.

In your program, there is no instantiation, so there is no instantiation that fails.

查看更多
来,给爷笑一个
3楼-- · 2020-02-07 00:38

Those pre-instantiation messages aren't enforced by the standard and are up to the compiler

n3337 § 14.6 - 8

No diagnostic shall be issued for a template definition for which a valid specialization can be generated. If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required.

emphasis mine

查看更多
登录 后发表回答