Для простой игры у меня есть следующие классы:
// color.h
#ifndef COLOR_H
#define COLOR_H
#include "ns.h"
BEGIN_NS
enum class color {
white,
black
};
END_NS
#endif
а также
// position.h
#ifndef POSITION_H
#define POSITION_H
#include <string>
#include "ns.h"
BEGIN_NS
struct position {
int rank, file; // The rank and file
public:
std::string code() const;
bool valid() const {
return rank >= 0 && rank < ranks && file >= 0 && file < files;
}
bool at(int r, int f) const { return rank == r && file == f; }
bool at(const position &p) const { return rank == p.rank && file == p.file; }
public:
static position from_code(std::string code);
};
END_NS
#endif
и наконец
#ifndef PIECE_H
#define PIECE_H
#include <string>
#include "color.h"
#include "position.h"
BEGIN_NS
class board;
class piece {
protected:
piece(const std::string& type, color c, const position &start_pos);
const color _color; // The color of the piece
const position _start_pos; // The initial starting position of this piece
position _pos; // The current position of the piece
int _times_moved; // The number of times the piece was moved
bool _captured; // Defines whether the piece has been captured
const std::string _type; // Defines the type of piece
public:
const position& start() const { return _start_pos; }
const position& position() const { return _pos; }
color color() const { return _color; }
bool captured() const { return _captured; }
int moved() const { return _times_moved; }
bool enemy_of(const piece* p) const { return p && p->color() != _color; }
bool ally_of(const piece* p) const { return p && p->color() == _color; }
void capture() { _captured = true; }
virtual piece* eval(const board* board, const position &pos) const = 0;
};
END_NS
#endif
Кроме того, макросы пространства имен определены в ns.h:
#define BEGIN_NS namespace chess_game {
#define END_NS }
Проблема заключается в использовании структуры позиции в моем файле pieces.h, особенно в виртуальной функции * eval (...). Компилятор не может разрешить позицию как допустимый тип, но он не жалуется на то, что позиция используется как конструктор arg, как два типа полей и как возвращаемый тип для функций start() и position(). В частности, компилятор говорит:
Функция IntelliSense "chess_game :: piece :: position" не является именем типа C4430: спецификатор отсутствующего типа - int предполагается. Примечание. C++ не поддерживает по умолчанию int C2143: синтаксическая ошибка: отсутствует ',' перед '&'
Тип параметра позиции в прототипе функции eval подчеркивается, но ни одно из других применений этого типа не подчеркивается. Если я полностью квалифицирую только этот экземпляр позиции с моим пространством имен, используя разрешение области, ошибка исчезнет. Если я удалю только функцию eval из класса, ошибка исчезнет. Почему для этого требуется, чтобы тип был полностью квалифицирован в сигнатуре параметра функции, а не где-либо еще в классе? Квалификация типа параметра с помощью пространства имен не имеет большого значения, я просто хочу знать, почему я должен и в чем проблема...
Компилятор Visual Studio 2013 C++
Спасибо за помощь.
class piece {
// ...
const position& position() const { return _pos; }
// ...
Функция-член chess_game::piece::position() const
скрывает тип chess_game::position()
в области piece
. После того, как функция-член объявлена, вы больше не можете использовать только position
для ссылки на класс.
Избегайте использования одного и того же имени для типа и функции.
chess_game::position
для обозначения класса и position
для обозначения функции-члена.
BEGIN_NS
иEND_NS
- ужасная идея.