Dependent type problem

K

Kaba

Hi,

GCC 4.4.5 gives compilation errors with the following code:

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

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

int main()
{
B<int> b;
b[2];
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]?

In contrast, Visual Studio 2008 and Comeau C++ compile this without
errors in strict modes.

Can you see any problems here, or is it a bug in GCC?
 
M

Michael Doubez

Hi,

GCC 4.4.5 gives compilation errors with the following code:

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

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

};

int main()
{
    B<int> b;
    b[2];
    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]?

In contrast, Visual Studio 2008 and Comeau C++ compile this without
errors in strict modes.

Can you see any problems here, or is it a bug in GCC?

Comeau seems to be happy with your code.

I am not familiar with C++0x but from §7.3.3 of n3126, I am not sure
using-declarations apply to types.

The usual idiom is rather to use a typedef:
typedef typename A<T>::C C;
 
K

Kaba

Michael said:
I am not familiar with C++0x but from §7.3.3 of n3126, I am not sure
using-declarations apply to types.

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)."

But whether this is in the 2003 standard too, I don't know.
The usual idiom is rather to use a typedef:
typedef typename A<T>::C C;

Yep, and by the quote above this should also be equivalent, and so an
obvious workaround.
 
J

Johannes Schaub (litb)

Kaba said:
Hi,

GCC 4.4.5 gives compilation errors with the following code:

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

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

int main()
{
B<int> b;
b[2];
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]?

In contrast, Visual Studio 2008 and Comeau C++ compile this without
errors in strict modes.

Can you see any problems here, or is it a bug in GCC?

This was a shortcoming of C++03 where this was underspecified, and is fixed
in C++0x.

Basically, when "C" is looked with the applicable name lookup to determine
whether it's a type name, it just finds that using declaration, which indeed
asserts with "typename" that it is a type, but that doesn't really guarantee
in C++03 that "C" is therefor assumed to be a type, even though of course it
was intended to be so.
 
J

Johannes Schaub (litb)

Kaba said:
Hi,

GCC 4.4.5 gives compilation errors with the following code:

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

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

int main()
{
B<int> b;
b[2];
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]?

In contrast, Visual Studio 2008 and Comeau C++ compile this without
errors in strict modes.

Can you see any problems here, or is it a bug in GCC?

You may want to read about typename/template in my dependent-name FAQ:
http://stackoverflow.com/questions/610245/where-to-put-the-template-and-
typename-on-dependent-names/613132#613132 . In the bottom section, you see
that you have a similar problem with "::template" disambiguation too.
 
K

Kaba

Johannes said:
This was a shortcoming of C++03 where this was underspecified, and is fixed
in C++0x.

Basically, when "C" is looked with the applicable name lookup to determine
whether it's a type name, it just finds that using declaration, which indeed
asserts with "typename" that it is a type, but that doesn't really guarantee
in C++03 that "C" is therefor assumed to be a type, even though of course it
was intended to be so.

Thanks for the info. I think I'll report this as a bug. The GCC should
either do the right thing or report a clear error.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top