The IMO well-formed program below fails to compile with g++ 3.3 (EDG 3.3 fails to compile it as well due to a bug; IBM VisualAge C++ 6.0 compiles it fine). For some discussion on the subject of pseudo-destructor calls see: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_defects.html#244 http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#399 Regards Martin $ cat t.cpp && g++ -c t.cpp /* 1 */ namespace N { /* 2 */ struct A { typedef A NA; }; /* 3 */ template <class T> struct B { typedef B NB; typedef T BT; }; /* 4 */ template <template <class> class T> struct C { typedef C NC; typedef T<A> CA; }; /* 5 */ } /* 6 */ /* 7 */ void foo (N::A *p) /* 8 */ { /* 9 */ p->~NA (); /* 10 */ p->NA::~NA (); /* 11 */ } /* 12 */ /* 13 */ template <class T> /* 14 */ void foo (N::B<T> *p) /* 15 */ { /* 16 */ p->~NB (); /* 17 */ p->NB::~NB (); /* 18 */ } /* 19 */ /* 20 */ template <class T> /* 21 */ void foo (typename N::B<T>::BT *p) /* 22 */ { /* 23 */ p->~BT (); /* 24 */ p->BT::~BT (); /* 25 */ } /* 26 */ /* 27 */ template <template <class> class T> /* 28 */ void foo (N::C<T> *p) /* 29 */ { /* 30 */ p->~NC (); /* 31 */ p->NC::~NC (); /* 32 */ } /* 33 */ /* 34 */ template <template <class> class T> /* 35 */ void foo (typename N::C<T>::CA *p) /* 36 */ { /* 37 */ p->~CA (); /* 38 */ p->CA::~CA (); /* 39 */ } /* 40 */ t.cpp: In function `void foo(N::B<T>*)': t.cpp:17: error: parse error before `::' token t.cpp: In function `void foo(typename N::B<T>::BT*)': t.cpp:24: error: parse error before `::' token t.cpp: In function `void foo(N::C<T>*)': t.cpp:31: error: parse error before `::' token t.cpp: In function `void foo(typename N::C<T>::CA*)': t.cpp:38: error: parse error before `::' token
On the mainline GCC produces: pr12228.cc: In function `void foo(N::B<T>*)': pr12228.cc:16: error: expected class-name pr12228.cc:17: error: expected `;' pr12228.cc: In function `void foo(typename N::B<T>::BT*)': pr12228.cc:23: error: expected class-name pr12228.cc:24: error: expected `;' pr12228.cc: In function `void foo(N::C<T>*)': pr12228.cc:30: error: expected class-name pr12228.cc:31: error: expected `;' pr12228.cc: In function `void foo(typename N::C<T>::CA*)': pr12228.cc:37: error: expected class-name pr12228.cc:38: error: expected `;'
Confirmed. I'd guess that at places one would need a template disambiguator, as in template <class T> void foo (N::B<T> *p) { p->template ~NB (); but that doesn't help. W.
Subject: Re: [DR 244/399] syntax error calling a qualified template dtor bangerth at dealii dot org wrote: ... > ------- Additional Comments From bangerth at dealii dot org 2003-09-09 21:03 ------- > Confirmed. I'd guess that at places one would need a template disambiguator, as in > template <class T> void foo (N::B<T> *p) { > p->template ~NB (); > but that doesn't help. You're right, although the keyword would actually have to go on the left of the :: operator, like here: namespace N { template <class> struct A { template <class> struct B { }; }; } template <class T, class U> void foo (typename N::A<T>::template B<U> *p) { p->N::A<T>::template B<U>::~B (); } Martin
Today's top of trunk (GCC 7.0) fails with the errors below. Clang also fails to compile it but EDG eccp, IBM XLC++, and Oracle Studio 12.4 all accept the code. t.C: In function ‘void foo(N::B<T>*)’: t.C:17:20: error: expected ‘;’ before ‘::’ token /* 17 */ p->NB::~NB (); ^~ t.C: In function ‘void foo(typename N::B<T>::BT*)’: t.C:24:20: error: expected ‘;’ before ‘::’ token /* 24 */ p->BT::~BT (); ^~ t.C: In function ‘void foo(N::C<T>*)’: t.C:31:20: error: expected ‘;’ before ‘::’ token /* 31 */ p->NC::~NC (); ^~ t.C: In function ‘void foo(typename N::C<T>::CA*)’: t.C:38:20: error: expected ‘;’ before ‘::’ token /* 38 */ p->CA::~CA (); ^~
Still rejected by current trunk, and https://wg21.link/cwg399 is still open.
CWG399 was resolved by P1787R6 <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html>. All of these definitions of foo are valid, although BT and CA will be found during instantiation only if the template arguments provide them as members.
(In reply to S. Davis Herring from comment #6) > CWG399 was resolved by P1787R6 > <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html>. All > of these definitions of foo are valid, although BT and CA will be found > during instantiation only if the template arguments provide them as members. Fixed on the trunk by r12-3643-g18b57c1d4a8777bedf which implements part of this paper.