Пространства имен, типы и один и тот же тип заголовочного файла с использованием директивы using распознаются как типы возвращаемых значений полей и функций, но не как типы параметров.

0

Для простой игры у меня есть следующие классы:

// 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++

Спасибо за помощь.

  • 0
    Использование BEGIN_NS и END_NS - ужасная идея.
  • 0
    Я передам это PJ Plauger
Показать ещё 1 комментарий
Теги:
visual-c++

1 ответ

2
Лучший ответ
class piece {
    // ...
    const position& position() const { return _pos; }
    // ...

Функция-член chess_game::piece::position() const скрывает тип chess_game::position() в области piece. После того, как функция-член объявлена, вы больше не можете использовать только position для ссылки на класс.

Избегайте использования одного и того же имени для типа и функции.

  • 0
    Я бы никогда, никогда, никогда не думал об этом. Огромное спасибо
  • 0
    В этом ответе не упоминается решение, если вы не хотите ничего переименовывать. Просто скажите chess_game::position для обозначения класса и position для обозначения функции-члена.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню