[Bug c++/87841] Member of class template hides template parameter of another member
redi at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Nov 1 11:25:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87841
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |rejects-valid
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
That example was changed by DR 458 https://wg21.link/cwg458
GCC compiles it if C is not used in the parameter-list:
template<class T> struct A {
struct B { /* ... */ };
typedef void C;
void f();
template<class U> void g();
};
template<class B> void A<B>::f() {
B b; // A's B, not the template parameter
}
template<class B> template<class C> void A<B>::g() {
B b; // A's B, not the template parameter
C c; // the template parameter C, not A's C
}
So GCC finds the right C in the function body. EDG also compiles that. Clang
doesn't:
dr458.cc:14:5: error: variable has incomplete type 'A::C' (aka 'void')
C c; // the template parameter C, not A's C
^
1 error generated.
However for the example as given in [temp.local] (as in comment 0) in the
standard, none of the compilers I tried accept it, because C in the function
parameter-list finds A<B>::C (aka void) not the function template parameter.
GCC says:
dr458.cc:12:42: error: no declaration matches 'void A<T>::g()'
12 | template<class B> template<class C> void A<B>::g(C) {
| ^~~~
dr458.cc:5:26: note: candidate is: 'template<class T> template<class U> void
A<T>::g(U)'
5 | template<class U> void g(U);
| ^
dr458.cc:1:26: note: 'struct A<T>' defined here
1 | template<class T> struct A {
| ^
EDG says:
"dr458.cc", line 12: error: a parameter may not have void type
template<class B> template<class C> void A<B>::g(C) {
^
"dr458.cc", line 12: error: declaration is incompatible with function template
"void A<T>::g(U)" (declared at line 5)
template<class B> template<class C> void A<B>::g(C) {
^
2 errors detected in the compilation of "dr458.cc".
Clang says:
dr458.cc:12:48: error: out-of-line definition of 'g' does not match any
declaration in 'A<T>'
template<class B> template<class C> void A<B>::g(C) {
^
dr458.cc:14:5: error: variable has incomplete type 'A::C' (aka 'void')
C c; // the template parameter C, not A's C
^
2 errors generated.
And VC++ says:
<source>(12): error C2244: 'A<T>::g': unable to match function definition to an
existing declaration
<source>(12): note: see declaration of 'A<T>::g'
<source>(12): note: definition
<source>(12): note: 'void A<T>::g(void)'
<source>(12): note: existing declarations
<source>(12): note: 'void A<T>::g(U)'
Compiler returned: 2
This makes me think the example in [temp.local] is wrong!
More information about the Gcc-bugs
mailing list