User account creation filtered due to spam.

Bug 46690

Summary: Using declaration of a dependent name
Product: gcc Reporter: ilpoilves
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Severity: normal Keywords: rejects-valid
Priority: P3    
Version: 4.4.5   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2010-11-28 12:08:05

Description ilpoilves 2010-11-28 09:35:43 UTC
Consider the following code:

template <typename T>
class A {public: typedef int C;};

template <typename T>
class B: public A<T> 
    using typename A<T>::C;
    C operator[](int i) const { return 0; }

int main()
    B<int> b;
    return 0;

The compilation gives:

test.cpp:9: error: ISO C++ forbids declaration of 'C' with no type
test.cpp:9: error: expected ';' before 'operator'
test.cpp:10: error: expected ';' before '}' token
test.cpp: In function 'int main()':
test.cpp:15: error: no match for 'operator[]' in 'b[2]'

A discussion in comp.lang.c++ revealed that this feature was underspecified in C++03. I propose the using declaration either just to work, or report a proper error.

To see the intent, consider the current wording for C++0x:

From n3126 (C++0x draft from August 2010), §7.3.3:

"20. If a using-declaration uses the keyword typename and specifies a 
dependent name (14.6.2), the name introduced
by the using-declaration is treated as a typedef-name (7.1.3)."

So the work-around here is 

typedef typename A<T>::C C;

which is equivalent.

The code above is accepted at least by Visual Studio 2008, 2010, and Comeau C++, all in strict mode.
Comment 1 ilpoilves 2010-11-28 09:38:04 UTC
Here is the result of gcc -v, which was left out by accident.

Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.4-8' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.4.5 20100728 (prerelease) (Debian 4.4.4-8)
Comment 2 Jonathan Wakely 2010-11-28 12:08:05 UTC
With 4.5 you get a much better error: error: ‘C’ does not name a type note: (perhaps ‘typename A<T>::C’ was intended) In function ‘int main()’: error: no match for ‘operator[]’ in ‘b[2]’

But it should be accepted
Comment 3 Andrew Pinski 2010-11-29 19:13:27 UTC
This is the same bug as PR 14258.

*** This bug has been marked as a duplicate of bug 14258 ***