typedef'd type not visible as return type of a

2019-02-11 01:33发布

问题:

This program fails to compile(using gcc-4.5). The error message says:

error: ‘myType_t’ does not name a type

  1 class abc{
  2 //typedef int myType_t;
  3 
  4   public:
  5 typedef int myType_t;
  6 
  7     abc();
  8     myType_t fun1();
  9 };
 10 
 11 myType_t abc::fun1()
 12 {
 13   return 0;
 14 }
 15 
 16 int main()
 17 {
 18   abc abc1;
 19   return 0;
 20 }

Now declaring typedef int myType_t; outside the class abc makes this compile. My confusion is, what is the problem if the return type of a member function is typedef'd inside the class.

回答1:

From the C++ Standard:

9.9 Nested type names [class.nested.type]

Type names obey exactly the same scope rules as other names.In particular, type names defined within a class definition cannot be used outside their class without qualification.

class X {
public :
   typedef int I;
   class Y { /  . . .  / };
   I a;
};

I b;            // error
Y c;            // error
X::Y d;         // OK
X::I e;         // OK

So You need to access it as:

abc::myType_t abc::fun1()


回答2:

myType_t abc::fun1()

Since myType_t is a nested type, so you've to write this :

  abc::myType_t  abc::fun1()
//^^^^^^^^^^^^^note this!

abc:: tells the compiler that myType_t is defined inside the class abc. You write abc::myType_t just in the same way you write abc::fun1(). But inside the class, you don't need to writeabc::, neither for myType_t, nor for fun1().



回答3:

This is because of a quirk in C++ syntax.

Because the member function's class is only precised at the moment where the name of the function itself is declared, anything before that must spell it out fully.

ReturnType
ClassName
::             // only here do we enter the scope 'ClassName'
FunctionName
(
  ArgumentType0,
  ArgumentType1,
  ...
) {
}

This can be overcomed using C++0x late return type syntax

auto
ClassName
::
FunctionName
(
  ArgumentType0,
  ArgumentType1,
  ...
)
->
ReturnType
{
}

Because it postpones the declaration of the return type long enough to enter the scope (it also allows to declare it based on the arguments of the function, using decltype for example).