Discussion:
using CLASS::type
(too old to reply)
Mycroft Holmes
2009-10-05 10:02:56 UTC
Permalink
Hi everyone,

We are having some problem with using declarations of the form "using
BASE_CLASS::type;".
Not sure this is allowed by the standard... most compilers (including
Comeau) accept it, but some give inconsistent results.
The code looks as follows:


template <typename T>
class my_base
{
public:
typedef T type;
};

template <typename T>
class my_object : public my_base<T>
{
public:
using typename my_base<T>::type;

type get_instance() const
{
return type();
}
};



class AAA
{
private:
class BBB
{
public:
int do_something() const { return 7; }
};

public:

int do_all() const
{ return my_object<BBB>().get_instance().do_something(); }
};



int main()
{
AAA myA;
return myA.do_all();
}




1) VC2008 returns error on "return type();"
error C2597: illegal reference to non-static member
'my_object<T>::type'

however if I change the code like this, it works:

type get_instance() const
{
type t; return t;




2) intel compiler 10.1 reports a strange error (something like
my_base<T>::type is not accessible from my_object). Actually, the
problem occurs because BBB is private inside AAA (if I make it public,
then it compiles just fine).


3) Comeau online accepts the code, so it shouldn't be too illegal


Note that the question is purely academic, since I could just re-
typedef "typedef typename BASE_CLASS::type type;" and get the same net
result (and all compilers behave correctly).

-- MH
Igor Tandetnik
2009-10-05 12:56:19 UTC
Permalink
Post by Mycroft Holmes
template <typename T>
class my_base
{
typedef T type;
};
template <typename T>
class my_object : public my_base<T>
{
using typename my_base<T>::type;
type get_instance() const
{
return type();
}
};
class AAA
{
class BBB
{
int do_something() const { return 7; }
};
int do_all() const
{ return my_object<BBB>().get_instance().do_something(); }
};
int main()
{
AAA myA;
return myA.do_all();
}
1) VC2008 returns error on "return type();"
error C2597: illegal reference to non-static member
'my_object<T>::type'
It is actually unclear whether the code is valid under the current
standard - see DR11:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#11

The latest draft of C++0x standard adds new wording that explicitly
allows this situation:

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

But no such wording exists in C++98.

In any case, you can achieve the same goal with

typedef typename my_base<T>::type type;
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
Loading...