解析问题 - 预期的 unqualified-id - #include <array> 编译错误
Parse Issue - Expected unqualified-id - #include <array> Compile Error
我目前正在使用 objective-c++ 构建这个 ios 纸牌游戏应用。不知为何,我开始遇到 Parse 问题 - Expected unqualified-id when trying to use #include <array>
。今天之前我从来没有遇到过这个问题。任何清晰度或方向将不胜感激!我已经仔细检查了我的编译器设置,以确保它知道我正在使用 C++。
Shows where the error is flagged
Compiler Settings
Compiler Settings
Shows Build time error
#ifndef Pack_hpp
#define Pack_hpp
#include "Card.hpp"
#include <array>
#include <string>
class Pack {
public:
Pack();
private:
//1 deck == 52 cards
//3 decks == 156
//6 decks == 312
static const int PACK_SIZE = 312;
std::array<Card, PACK_SIZE> cards;
int next; //index of next card to be dealt
};
错误日志
In file included from /Users/MM/Documents/C++PROJECTS/C++CoreGame/Pack.cpp:9:
In file included from /Users/MM/Documents/C++PROJECTS/C++CoreGame/Pack.hpp:18:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/array:123:1: error: expected unqualified-id
_LIBCPP_BEGIN_NAMESPACE_STD
^
In file included from /Users/MM/Documents/C++PROJECTS/C++CoreGame/Pack.cpp:9:
In file included from /Users/MM/Documents/C++PROJECTS/C++CoreGame/Pack.hpp:17:
In file included from /Users/MM/Documents/C++PROJECTS/C++CoreGame/Card.hpp:13:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/string:503:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__config:866:37: note: expanded from macro '_LIBCPP_BEGIN_NAMESPACE_STD'
#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_ABI_NAMESPACE {
^
1 error generated.
Card.cpp
#include "Card.hpp"
#include <iostream>
#include <string>
Card::Card()
: rank(), suit() {}
//REQUIRES rank is one of "Two", "Three", "Four", "Five", "Six", "Seven",
// "Eight", "Nine", "Ten", "Jack", "Queen", "King", "Ace"
// suit is one of "Spades", "Hearts", "Clubs", "Diamonds"
//EFFECTS Initializes Card to specified rank and suit
Card::Card(const std::string &rank_in, const std::string &suit_in)
: rank(rank_in), suit(suit_in) {}
//EFFECTS Returns the rank
std::string Card::get_rank() const
{
return rank;
}
//EFFECTS Returns the suit. Does not consider trump.
std::string Card::get_suit() const
{
return suit;
}
//EFFECTS Returns true if card is a face card (Jack, Queen, King or Ace)
bool Card::is_face() const
{
if((get_rank() == Card::RANK_JACK) || (get_rank() == Card::RANK_QUEEN) || (get_rank() == Card::RANK_KING)|| (get_rank() == Card::RANK_ACE))
{
return true;
}
else
{
return false;
}
}
//EFFECTS Returns true if lhs is lower value than rhs.
// Does not consider trump.
bool operator<(const Card &lhs, const Card &rhs)
{
int lhs_RankWeight = 0;
int rhs_RankWeight = 0;
for (int i = 0; i < NUM_RANKS; i++)
{
if (lhs.get_rank() == RANK_NAMES_BY_WEIGHT[i])
{
lhs_RankWeight = i;
}
if (rhs.get_rank() == RANK_NAMES_BY_WEIGHT[i])
{
rhs_RankWeight = i;
}
}
//compare left hand and right hand weights
if (lhs_RankWeight < rhs_RankWeight)
{
return true;
}
else
{
return false;
}
}
//EFFECTS Returns true if lhs is higher value than rhs.
// Does not consider trump.
bool operator>(const Card &lhs, const Card &rhs)
{
int lhs_RankWeight = 0;
int rhs_RankWeight = 0;
for (int i = 0; i < NUM_RANKS; i++)
{
if (lhs.get_rank() == RANK_NAMES_BY_WEIGHT[i])
{
lhs_RankWeight = i;
}
if (rhs.get_rank() == RANK_NAMES_BY_WEIGHT[i])
{
rhs_RankWeight = i;
}
}
//compare left hand and right hand weights
if (lhs_RankWeight > rhs_RankWeight)
{
return true;
}
else
{
return false;
}
}
//EFFECTS Returns true if lhs is same card as rhs.
// Does not consider trump.
bool operator==(const Card &lhs, const Card &rhs)
{
if (((lhs.get_suit() == rhs.get_suit()) && (lhs.get_rank() == rhs.get_rank())))
{
return true;
}
else
{
return false;
}
}
//EFFECTS Returns true if lhs is not the same card as rhs.
// Does not consider trump.
bool operator!=(const Card &lhs, const Card &rhs)
{
if (((lhs.get_suit() != rhs.get_suit()) || (lhs.get_rank() != rhs.get_rank())))
{
return true;
}
else
{
return false;
}
}
//REQUIRES suit is a valid suit
//EFFECTS returns the next suit, which is the suit of the same color
std::string Suit_next(const std::string &suit)
{
if(suit == Card::SUIT_SPADES)
{
return Card::SUIT_CLUBS;
}
if(suit == Card::SUIT_CLUBS)
{
return Card::SUIT_HEARTS;
}
if(suit == Card::SUIT_HEARTS)
{
return Card::SUIT_DIAMONDS;
}
if(suit == Card::SUIT_DIAMONDS)
{
return Card::SUIT_SPADES;
}
return 0;
}
//EFFECTS Prints Card to stream, for example "Two of Spades"
std::ostream & operator<<(std::ostream &os, const Card &card)
{
return os << card.get_rank() << " of " << card.get_suit();
}
Card.hpp
#ifndef Card_hpp
#define Card_hpp
#include <iostream>
#include <string>
#include <stdio.h>
class Card
{
public:
int value;
// rank and suit names
static constexpr const char* const RANK_TWO = "Two";
static constexpr const char* const RANK_THREE = "Three";
static constexpr const char* const RANK_FOUR = "Four";
static constexpr const char* const RANK_FIVE = "Five";
static constexpr const char* const RANK_SIX = "Six";
static constexpr const char* const RANK_SEVEN = "Seven";
static constexpr const char* const RANK_EIGHT = "Eight";
static constexpr const char* const RANK_NINE = "Nine";
static constexpr const char* const RANK_TEN = "Ten";
static constexpr const char* const RANK_JACK = "Jack";
static constexpr const char* const RANK_QUEEN = "Queen";
static constexpr const char* const RANK_KING = "King";
static constexpr const char* const RANK_ACE = "Ace";
static constexpr const char* const SUIT_SPADES = "Spades";
static constexpr const char* const SUIT_HEARTS = "Hearts";
static constexpr const char* const SUIT_CLUBS = "Clubs";
static constexpr const char* const SUIT_DIAMONDS = "Diamonds";
//EFFECTS Initializes Card to empty hand
Card();
//REQUIRES rank is one of "Two", "Three", "Four", "Five", "Six", "Seven",
// "Eight", "Nine", "Ten", "Jack", "Queen", "King", "Ace"
// suit is one of "Spades", "Hearts", "Clubs", "Diamonds"
//EFFECTS Initializes Card to specified rank and suit
Card(const std::string &rank_in, const std::string &suit_in);
//EFFECTS Returns the rank
std::string get_rank() const;
//EFFECTS Returns the suit.
std::string get_suit() const;
//EFFECTS Returns true if card is a face card (Jack, Queen, King or Ace)
bool is_face() const;
private:
std::string rank;
std::string suit;
};
// Suits in order from lowest suit to highest suit.
constexpr const char* const SUIT_NAMES_BY_WEIGHT[] = {
Card::SUIT_SPADES,
Card::SUIT_HEARTS,
Card::SUIT_CLUBS,
Card::SUIT_DIAMONDS
};
const int NUM_SUITS = 4;
// Ranks in order from lowest rank to highest rank.
constexpr const char* const RANK_NAMES_BY_WEIGHT[] = {
Card::RANK_TWO,
Card::RANK_THREE,
Card::RANK_FOUR,
Card::RANK_FIVE,
Card::RANK_SIX,
Card::RANK_SEVEN,
Card::RANK_EIGHT,
Card::RANK_NINE,
Card::RANK_TEN,
Card::RANK_JACK,
Card::RANK_QUEEN,
Card::RANK_KING,
Card::RANK_ACE
};
const int NUM_RANKS = 13;
//EFFECTS Returns true if lhs is lower value than rhs.
// Does not consider trump.
bool operator<(const Card &lhs, const Card &rhs);
//EFFECTS Returns true if lhs is higher value than rhs.
// Does not consider trump.
bool operator>(const Card &lhs, const Card &rhs);
//EFFECTS Returns true if lhs is same card as rhs.
// Does not consider trump.
bool operator==(const Card &lhs, const Card &rhs);
//EFFECTS Returns true if lhs is not the same card as rhs.
// Does not consider trump.
bool operator!=(const Card &lhs, const Card &rhs);
//REQUIRES suit is a valid suit
//EFFECTS returns the next suit, which is the suit of the same color
std::string Suit_next(const std::string &suit);
//EFFECTS Prints Card to stream, for example "Two of Spades"
std::ostream & operator<<(std::ostream &os, const Card &card);
#endif
*
注意:问题自最初发布以来已经发生了很大变化。这是最终答案,但我会保留我之前写的内容。
问题是单独的星号 (*
) 似乎偷偷溜进了您的 Card.hpp
文件的末尾。
错误出现在 <array>
中的原因是因为 #include
只是执行文本替换,并且因为 <array>
紧接在 Card.hpp
之后包含在 [=18] 中=]:
#include "Card.hpp"
#include <array>
星号可能不是问题,这取决于它后面的内容,但是里面的代码<array>
当然不会指望跟随一个流氓*
,因此编译错误。
上一个答案 - 为后代保留 - 这是为了回应仅包含 Pack.hpp
的问题而发布的。按照下面的评论了解我们最终是如何得到答案的。
包括守卫
#ifndef Pack_hpp
#define Pack_hpp
表明此代码来自名为 Pack.hpp
的文件,即头文件。
我怀疑它是直接或间接从 .m
(纯 Objective-C)文件中包含的,并且 Objective-C 编译器无法理解此 C++ 代码。 (在这种情况下,Transitivity 表示它被另一个头文件包含,而另一个头文件被 .m
文件包含,或者它被另一个头文件包含的头文件包含,等等。最终形成一个链导致头文件直接包含在 .m
文件中。)
请确保您仅 #include
此文件来自 .cpp
或 .mm
个文件。
注意clang
在打印错误的时候实际上会告诉你#include
链,你只需要跟着它回到编译单元的文件来识别问题。
模仿@pmdj 的回答,我遇到了同样的问题——这次在 AVAnimation 中弹出构建错误(我正在导入 AVFoundation)。
我的答案是我忘记添加一个字符——C++}
结束后的;
class 完全在不同的文件中:
class SubclassSomething : public Something {
}; // <-----
直到我注释掉导致构建错误的 AVFoundation 导入行,Xcode 才真正告诉我是什么原因造成的。
我目前正在使用 objective-c++ 构建这个 ios 纸牌游戏应用。不知为何,我开始遇到 Parse 问题 - Expected unqualified-id when trying to use #include <array>
。今天之前我从来没有遇到过这个问题。任何清晰度或方向将不胜感激!我已经仔细检查了我的编译器设置,以确保它知道我正在使用 C++。
Shows where the error is flagged
Compiler Settings
Compiler Settings
Shows Build time error
#ifndef Pack_hpp
#define Pack_hpp
#include "Card.hpp"
#include <array>
#include <string>
class Pack {
public:
Pack();
private:
//1 deck == 52 cards
//3 decks == 156
//6 decks == 312
static const int PACK_SIZE = 312;
std::array<Card, PACK_SIZE> cards;
int next; //index of next card to be dealt
};
错误日志
In file included from /Users/MM/Documents/C++PROJECTS/C++CoreGame/Pack.cpp:9:
In file included from /Users/MM/Documents/C++PROJECTS/C++CoreGame/Pack.hpp:18:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/array:123:1: error: expected unqualified-id
_LIBCPP_BEGIN_NAMESPACE_STD
^
In file included from /Users/MM/Documents/C++PROJECTS/C++CoreGame/Pack.cpp:9:
In file included from /Users/MM/Documents/C++PROJECTS/C++CoreGame/Pack.hpp:17:
In file included from /Users/MM/Documents/C++PROJECTS/C++CoreGame/Card.hpp:13:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/string:503:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__config:866:37: note: expanded from macro '_LIBCPP_BEGIN_NAMESPACE_STD'
#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_ABI_NAMESPACE {
^
1 error generated.
Card.cpp
#include "Card.hpp"
#include <iostream>
#include <string>
Card::Card()
: rank(), suit() {}
//REQUIRES rank is one of "Two", "Three", "Four", "Five", "Six", "Seven",
// "Eight", "Nine", "Ten", "Jack", "Queen", "King", "Ace"
// suit is one of "Spades", "Hearts", "Clubs", "Diamonds"
//EFFECTS Initializes Card to specified rank and suit
Card::Card(const std::string &rank_in, const std::string &suit_in)
: rank(rank_in), suit(suit_in) {}
//EFFECTS Returns the rank
std::string Card::get_rank() const
{
return rank;
}
//EFFECTS Returns the suit. Does not consider trump.
std::string Card::get_suit() const
{
return suit;
}
//EFFECTS Returns true if card is a face card (Jack, Queen, King or Ace)
bool Card::is_face() const
{
if((get_rank() == Card::RANK_JACK) || (get_rank() == Card::RANK_QUEEN) || (get_rank() == Card::RANK_KING)|| (get_rank() == Card::RANK_ACE))
{
return true;
}
else
{
return false;
}
}
//EFFECTS Returns true if lhs is lower value than rhs.
// Does not consider trump.
bool operator<(const Card &lhs, const Card &rhs)
{
int lhs_RankWeight = 0;
int rhs_RankWeight = 0;
for (int i = 0; i < NUM_RANKS; i++)
{
if (lhs.get_rank() == RANK_NAMES_BY_WEIGHT[i])
{
lhs_RankWeight = i;
}
if (rhs.get_rank() == RANK_NAMES_BY_WEIGHT[i])
{
rhs_RankWeight = i;
}
}
//compare left hand and right hand weights
if (lhs_RankWeight < rhs_RankWeight)
{
return true;
}
else
{
return false;
}
}
//EFFECTS Returns true if lhs is higher value than rhs.
// Does not consider trump.
bool operator>(const Card &lhs, const Card &rhs)
{
int lhs_RankWeight = 0;
int rhs_RankWeight = 0;
for (int i = 0; i < NUM_RANKS; i++)
{
if (lhs.get_rank() == RANK_NAMES_BY_WEIGHT[i])
{
lhs_RankWeight = i;
}
if (rhs.get_rank() == RANK_NAMES_BY_WEIGHT[i])
{
rhs_RankWeight = i;
}
}
//compare left hand and right hand weights
if (lhs_RankWeight > rhs_RankWeight)
{
return true;
}
else
{
return false;
}
}
//EFFECTS Returns true if lhs is same card as rhs.
// Does not consider trump.
bool operator==(const Card &lhs, const Card &rhs)
{
if (((lhs.get_suit() == rhs.get_suit()) && (lhs.get_rank() == rhs.get_rank())))
{
return true;
}
else
{
return false;
}
}
//EFFECTS Returns true if lhs is not the same card as rhs.
// Does not consider trump.
bool operator!=(const Card &lhs, const Card &rhs)
{
if (((lhs.get_suit() != rhs.get_suit()) || (lhs.get_rank() != rhs.get_rank())))
{
return true;
}
else
{
return false;
}
}
//REQUIRES suit is a valid suit
//EFFECTS returns the next suit, which is the suit of the same color
std::string Suit_next(const std::string &suit)
{
if(suit == Card::SUIT_SPADES)
{
return Card::SUIT_CLUBS;
}
if(suit == Card::SUIT_CLUBS)
{
return Card::SUIT_HEARTS;
}
if(suit == Card::SUIT_HEARTS)
{
return Card::SUIT_DIAMONDS;
}
if(suit == Card::SUIT_DIAMONDS)
{
return Card::SUIT_SPADES;
}
return 0;
}
//EFFECTS Prints Card to stream, for example "Two of Spades"
std::ostream & operator<<(std::ostream &os, const Card &card)
{
return os << card.get_rank() << " of " << card.get_suit();
}
Card.hpp
#ifndef Card_hpp
#define Card_hpp
#include <iostream>
#include <string>
#include <stdio.h>
class Card
{
public:
int value;
// rank and suit names
static constexpr const char* const RANK_TWO = "Two";
static constexpr const char* const RANK_THREE = "Three";
static constexpr const char* const RANK_FOUR = "Four";
static constexpr const char* const RANK_FIVE = "Five";
static constexpr const char* const RANK_SIX = "Six";
static constexpr const char* const RANK_SEVEN = "Seven";
static constexpr const char* const RANK_EIGHT = "Eight";
static constexpr const char* const RANK_NINE = "Nine";
static constexpr const char* const RANK_TEN = "Ten";
static constexpr const char* const RANK_JACK = "Jack";
static constexpr const char* const RANK_QUEEN = "Queen";
static constexpr const char* const RANK_KING = "King";
static constexpr const char* const RANK_ACE = "Ace";
static constexpr const char* const SUIT_SPADES = "Spades";
static constexpr const char* const SUIT_HEARTS = "Hearts";
static constexpr const char* const SUIT_CLUBS = "Clubs";
static constexpr const char* const SUIT_DIAMONDS = "Diamonds";
//EFFECTS Initializes Card to empty hand
Card();
//REQUIRES rank is one of "Two", "Three", "Four", "Five", "Six", "Seven",
// "Eight", "Nine", "Ten", "Jack", "Queen", "King", "Ace"
// suit is one of "Spades", "Hearts", "Clubs", "Diamonds"
//EFFECTS Initializes Card to specified rank and suit
Card(const std::string &rank_in, const std::string &suit_in);
//EFFECTS Returns the rank
std::string get_rank() const;
//EFFECTS Returns the suit.
std::string get_suit() const;
//EFFECTS Returns true if card is a face card (Jack, Queen, King or Ace)
bool is_face() const;
private:
std::string rank;
std::string suit;
};
// Suits in order from lowest suit to highest suit.
constexpr const char* const SUIT_NAMES_BY_WEIGHT[] = {
Card::SUIT_SPADES,
Card::SUIT_HEARTS,
Card::SUIT_CLUBS,
Card::SUIT_DIAMONDS
};
const int NUM_SUITS = 4;
// Ranks in order from lowest rank to highest rank.
constexpr const char* const RANK_NAMES_BY_WEIGHT[] = {
Card::RANK_TWO,
Card::RANK_THREE,
Card::RANK_FOUR,
Card::RANK_FIVE,
Card::RANK_SIX,
Card::RANK_SEVEN,
Card::RANK_EIGHT,
Card::RANK_NINE,
Card::RANK_TEN,
Card::RANK_JACK,
Card::RANK_QUEEN,
Card::RANK_KING,
Card::RANK_ACE
};
const int NUM_RANKS = 13;
//EFFECTS Returns true if lhs is lower value than rhs.
// Does not consider trump.
bool operator<(const Card &lhs, const Card &rhs);
//EFFECTS Returns true if lhs is higher value than rhs.
// Does not consider trump.
bool operator>(const Card &lhs, const Card &rhs);
//EFFECTS Returns true if lhs is same card as rhs.
// Does not consider trump.
bool operator==(const Card &lhs, const Card &rhs);
//EFFECTS Returns true if lhs is not the same card as rhs.
// Does not consider trump.
bool operator!=(const Card &lhs, const Card &rhs);
//REQUIRES suit is a valid suit
//EFFECTS returns the next suit, which is the suit of the same color
std::string Suit_next(const std::string &suit);
//EFFECTS Prints Card to stream, for example "Two of Spades"
std::ostream & operator<<(std::ostream &os, const Card &card);
#endif
*
注意:问题自最初发布以来已经发生了很大变化。这是最终答案,但我会保留我之前写的内容。
问题是单独的星号 (*
) 似乎偷偷溜进了您的 Card.hpp
文件的末尾。
错误出现在 <array>
中的原因是因为 #include
只是执行文本替换,并且因为 <array>
紧接在 Card.hpp
之后包含在 [=18] 中=]:
#include "Card.hpp"
#include <array>
星号可能不是问题,这取决于它后面的内容,但是里面的代码<array>
当然不会指望跟随一个流氓*
,因此编译错误。
上一个答案 - 为后代保留 - 这是为了回应仅包含 Pack.hpp
的问题而发布的。按照下面的评论了解我们最终是如何得到答案的。
包括守卫
#ifndef Pack_hpp
#define Pack_hpp
表明此代码来自名为 Pack.hpp
的文件,即头文件。
我怀疑它是直接或间接从 .m
(纯 Objective-C)文件中包含的,并且 Objective-C 编译器无法理解此 C++ 代码。 (在这种情况下,Transitivity 表示它被另一个头文件包含,而另一个头文件被 .m
文件包含,或者它被另一个头文件包含的头文件包含,等等。最终形成一个链导致头文件直接包含在 .m
文件中。)
请确保您仅 #include
此文件来自 .cpp
或 .mm
个文件。
注意clang
在打印错误的时候实际上会告诉你#include
链,你只需要跟着它回到编译单元的文件来识别问题。
模仿@pmdj 的回答,我遇到了同样的问题——这次在 AVAnimation 中弹出构建错误(我正在导入 AVFoundation)。
我的答案是我忘记添加一个字符——C++}
结束后的;
class 完全在不同的文件中:
class SubclassSomething : public Something {
}; // <-----
直到我注释掉导致构建错误的 AVFoundation 导入行,Xcode 才真正告诉我是什么原因造成的。