2013-03-20 45 views
2
typedef int abc; 

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

在上面的代码中的参数列表里,我明白了,我得到一个错误:因为在这本书名称查找成员函数

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

C++底漆,第五edtion,它说:

Class definitions are processed in two phases:

1.First, the member declarations are compiled.

2.Function bodies are compiled only after the entire class has been seen.

但在这里的代码:

typedef int abc; 

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

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

+0

您的问题是? – Oswald 2013-03-20 13:56:10

+0

我的不好。我编辑它。 – longtengaa 2013-03-20 14:04:14

回答

1

我不认为有任何理由。这个错误不需要诊断(根据标准C++),所以当你的代码中有这个错误时,行为是不确定的。

你的编译器还没有检查过这个错误的参数列表,但可能已经完成了。

0

你需要限定它,Some::abc

typedef int abc; 

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

是的,我知道。但我在这里问的是为什么后面的代码不会像前者那样提示错误。 – longtengaa 2013-03-20 13:54:48

+0

如果你想知道为什么后面的代码不会像前者那样提示错误,你应该在问题中这样说,而不是在答案的评论中。 – Oswald 2013-03-20 13:58:59

+0

对不起,我只是忘记了..... – longtengaa 2013-03-20 14:03:10

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 
} 
+0

但是在整个班级被看到之后,不应该编译函数体吗? – longtengaa 2013-05-29 15:03:10

0

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

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