在成员函数的参数列表中查找名称

时间:2013-03-20 13:49:40

标签: c++ name-lookup

typedef int abc;

class Some{
   public:
      abc foo(){...}
      typedef double abc;
};

在上面的代码中,我得到了一个错误:

error: changes meaning of 'abc' from 'typedef int abc'

因为在书中 c ++ primer,第五版,它说:

  

类定义分两个阶段处理:

     

1.首先,编译成员声明

     

2.仅在看到整个类之后才编译函数体。

但是在这里的代码中:

typedef int abc;

class Some{
     public:
        int foo(abc){...}
        typedef double abc;
};

我在参数列表中设置了abc。 但我没有得到那种错误,编译器工作得很好。 为什么后面的代码不会给我任何类似于前者的错误?

4 个答案:

答案 0 :(得分:1)

我认为没有任何理由。此错误不需要诊断(根据标准C ++),因此当您的代码中出现此错误时,行为实际上是未定义的。

您的编译器尚未检查参数列表中是否存在此错误,但可能已完成此操作。

答案 1 :(得分:0)

您需要对其进行限定,Some::abc

typedef int abc;

class Some{
   public:
      Some::abc foo(){...}
      typedef double abc;
};

答案 2 :(得分:0)

第一个示例给出错误的原因是名称查找没有考虑返回类型。但是当在调用它的表达式中生成实际的函数体时,编译器将使用Some::abc并找出差异。

typedef int abc;

class Some{
   public:
      abc foo() { return abc(); }  // during lookup/resolution, "abc" is known to be int, return type is not considered
      typedef double abc;
};

int main() 
{ 
    Some s; 
    int x = s.foo(); // kaboom, return type is double.
}

在第二个示例中,类型重新定义是无关紧要的,因为在名称查找期间,abc已知为int,因为尚未看到内部typedef的定义。在调用站点的函数实例期间没有任何后果,因为返回类型也是int。根本没有不匹配。

typedef int abc;

class Some{
   public:
      int foo(abc) { return int(); }  // during lookup/resolution, "abc" is known to be int
      typedef double abc;             // this will not have been seen yet in the previous line
};

int main() 
{ 
    Some s; 
    int x = 0;
    s.foo(x); // OK, x is of type int
}

答案 3 :(得分:0)

在MinGW中,如果成员函数的返回类型显示为typedef声明定义的别名类型。不允许改变其含义。 您要求的名称查找规则仍然有效,如第447页的Lippman C ++入门中所介绍的那样 - 类成员声明的名称查找。

  1. 考虑在使用名称之前出现的类成员的声明。
  2. 如果步骤1中的查找不成功,则会考虑出现在定义类的范围内以及出现在类定义本身之前的声明。