xcode C++ 奇怪的编译错误:错误:从类“Object”更改“Object”的含义

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/282800/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 18:25:39  来源:igfitidea点击:

C++ odd compile error: error: changes meaning of "Object" from class "Object"

c++xcode

提问by epochwolf

I don't even know where to go with this. Google wasn't very helpful. As with my previous question. I'm using TextMate's Command+R to compile the project.

我什至不知道该怎么办。谷歌不是很有帮助。和我之前的问题一样。我正在使用 TextMate 的 Command+R 来编译项目。

game.h:16:error: declaration of ‘Player* HalfSet::Player() const'

players.h:11:error: changes meaning of ‘Player' from ‘class Player'

game.h:21:error: ‘Player' is not a type

game.h:16:error: 'Player* HalfSet::Player() const'的声明

player.h:11:error: 从“class Player”改变“Player”的含义

game.h:21:error: 'Player' 不是一个类型

player.h file (partial)

player.h 文件(部分)

#ifndef PLAYERS_H
#define PLAYERS_H
using namespace std;

#include <string>
#include <vector>
#include <istream>
#include <iomanip>
#include "generics.h"

class Player{ //Line 11
public:
    //getters
    long Id() const;
    string FirstName() const;
    string LastName() const;
    string Country() const;
    //setters
    void setId(long id);
    void setFirstName(string s);
    void setLastName(string s);
    void setCountry(string s);
    //serializing functions
    void display(ostream &out);
    void read(istream &in);
    void write(ostream &out);
    //Initalizers
    Player();
    Player(istream &in);
    Player(string firstName, string lastName);
    Player(string firstName, string lastName, string country);
    Player(long id, string firstName, string lastName, string country);
    ~Player();
private:
    long _id;
    string _firstName;
    string _lastName;
    string _country;
};

game.h file (partial)

game.h 文件(部分)

#ifndef GAME_H
#define GAME_H

#include "generics.h"
#include "players.h"
#include <string>
#include <vector>
#include <istream>
#include <iomanip>

using namespace std;

class HalfSet{
public:
    //getters
    Player* Player() const; //Line 16
    int GamesWon() const;
    int TotalPoints() const;
    int Errors() const;
    //setters
    void setPlayer(Player* p);
    void setGamesWon(int games);
    void setTotalPoints(int points);
    void setErrors(int errors);
    //Serialization
    void display(ostream &out) const;
    void read(istream &in) const;
    void write(ostream &out) const;
    //Initalizers
    HalfSet();
    ~HalfSet();
private:
    Player* _player;
    int _gamesWon;
    int _points;
    int _errors;
};

What is going on here?

这里发生了什么?

回答by SoapBox

In C++ you cannot name a function the same name as a class/struct/typedef. You have a class named "Player" and so the HalfSet class has a function named "Player" ("Player *Player()"). You need to rename one of these (probably changing HalfSet's Player() to getPlayer() or somesuch).

在 C++ 中,您不能将函数命名为与类/结构/类型定义相同的名称。您有一个名为“Player”的类,因此HalfSet 类有一个名为“Player”的函数(“Player *Player()”)。您需要重命名其中之一(可能将 HalfSet 的 Player() 更改为 getPlayer() 或类似名称)。

回答by MSalters

Your problem is that names are looked up in scopes. Within the declaration of HalfSet::setPlayer(Player*), the unqualified name Playerneeds to be looked up. The first scope tried is class HalfSet. In that scope, the lookup of Playerfinds function HalfSet::Player, not global class ::Player.

您的问题是在范围内查找名称。在 的声明中HalfSet::setPlayer(Player*)Player需要查找不合格的名称。尝试的第一个范围是class HalfSet. 在该范围内,查找Playerfind 函数HalfSet::Player,而不是global class ::Player.

The solution is to use a qualified name, ::Player. This tells the compiler which scope to use for lookup (global) which in turn means HalfSet::Playeris not even considered.

解决方案是使用限定名称::Player. 这告诉编译器用于查找(全局)的范围,这反过来意味着HalfSet::Player甚至不考虑。

回答by Shafik Yaghmour

The current answer to this question is just incorrect, it says:

这个问题的当前答案是不正确的,它说:

In C++ you cannot name a function the same name as a class/struct/typedef

在 C++ 中,您不能将函数命名为与类/结构体/typedef 相同的名称

Name hiding of a class by a function is allowed, if we go to the draft Pre C++11 standardsection 3.3.7Name hidingit says:

允许通过函数对类进行名称隐藏,如果我们转到Pre C++11 标准部分的草案3.3.7名称隐藏它说:

A class name (9.1) or enumeration name (7.2) can be hidden by the name of an object, function, or enumerator declared in the same scope. If a class or enumeration name and an object, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the object, function, or enumerator name is visible.

类名 (9.1) 或枚举名 (7.2) 可以被同一作用域中声明的对象、函数或枚举器的名称隐藏。如果类或枚举名称和对象、函数或枚举器在同一范围内(以任何顺序)以相同的名称声明,则在对象、函数或枚举器名称可见的任何地方,类或枚举名称都将隐藏。

So the fact that you have the function and a class named Playeris not the issue, in fact the following code is valid:

因此,您拥有函数和命名的类的Player事实不是问题,实际上以下代码是有效的:

class Player
{
} ;

Player* Player() ;

and we can use an elaborated type specifierto un-hide the class type.

我们可以使用详细的类型说明符来取消隐藏类类型。

As far as I can tell this is violating section 3.3.6Class scopeparagraph 2which says:

据我所知,这违反了3.3.6类范围段落2,其中说:

A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.

在类 S 中使用的名称 N 应在其上下文中以及在 S 的完整范围内重新评估时引用相同的声明。违反此规则不需要诊断。

So in this case Playerchanges meaning from classto a function, it is not clear to me it was intended so strictly but I can see how it could be read that way. This seems to be the message gccuses when it detects this violation as we can see from a similar question.

因此,在这种情况下,Player改变从意功能,它是我不清楚它的目的是使严格的,但我可以看到它如何被读取的方式。gcc类似的问题中可以看出,这似乎是检测到此违规时使用的消息。

Using an elaborated type specifier prevents the change of meaning:

使用详细的类型说明符可以防止含义的改变:

class Player* Player() const ;