我试图将constexpr静态结构数组声明为类成员,但是当我编译以下代码时:
#include<iostream>
#include<assert.h>
using namespace std;
typedef enum token_t {INTEGER,SIGN,EOE} token_t;
class Token{
token_t type;
int value;
constexpr static struct token_d {
token_t id;
const char* name;
} token_dump[] = {
{INTEGER,"INTEGER"},
{SIGN,"SIGN"},
{EOE,"EOE"}
};
public:
const char* get_token_type ();
Token(token_t,int);
};
constexpr struct token_d Token::token_dump[];
const char* Token::get_token_type () {
return token_dump[type].name;
};
Token::Token (token_t TokenType,int TokenValue) {
type = TokenType;
value = TokenValue;
};
int main()
{
Token token1(INTEGER,2);
cout<<token1.get_token_type();
return 0;
}
我收到以下错误消息:
calc1.cpp:29:44: error: conflicting declaration ‘constexpr const token_d Token::token_dump []’
constexpr struct token_d Token::token_dump[];
^
calc1.cpp:18:5: note: previous declaration as ‘constexpr const Token::token_d Token::token_dump [3]’
} token_dump[] = {
^~~~~~~~~~
calc1.cpp:29:44: error: declaration of ‘constexpr const Token::token_d Token::token_dump [3]’ outside of class is not definition [-fpermissive]
constexpr struct token_d Token::token_dump[];
我如何定义token_dump []?我无法弄清楚。
calc1.cpp:29:44:错误:冲突声明'constexpr const token_d Token :: token_dump []'constexpr struct token_d 令牌:: token_dump []; ^ calc1.cpp:18:5:注意:之前的声明为'constexpr const Token :: token_d Token :: token_dump [3]'} token_dump [] = { ^ ~~~~~~~~~ calc1.cpp:29:44:错误:在类之外声明'constexpr const Token :: token_d Token :: token_dump [3]' definition [-fpermissive] constexpr struct token_d 令牌:: token_dump [];
答案 0 :(得分:1)
相关的代码行应为:
constexpr Token::token_d Token::token_dump[];
当您在struct token_d
中定义class Token
时,这意味着您正在定义结构Token::token_d
,换句话说,它是作用于该类的范围。全局范围内没有名称token_d
。
当您在全局范围内编写struct token_d
时,它会在全局范围内将token_d
声明为结构类型,该类型当前是不完整类型,与Token::token_d
无关。因此类型不匹配。
我建议不要写struct T
来引用预先存在的T
,原因正是如此(除其他外):如果您尝试引用预先存在的T
但是你犯了一个错误,它会声明一个新的不完整类型,而不是在某些情况下给出错误。
关于需要对静态类成员变量进行类外定义的讨论:C ++ 17正在添加内联变量的概念,这与内联函数非常相似您可以在标头中定义内联变量,编译器将其全部排序。变量定义上的constexpr
意味着inline
。但是在C ++ 17之前,您仍然需要手动选择一个翻译单元来放置一个类外定义。
答案 1 :(得分:0)
我刚刚在wandbox验证了它,(我不是100%确定这会编译,因为你使用了一些C风格的约定)但是阻止这段代码的所有内容都是你{{1}的第二个声明}}。与其他token_dump
变量一样,static constexpr
变量是内联定义的。它们忽略了在外部定义的正常类静态要求。
我无法在C ++ 17以下的任何在线编译器中编译此代码。 This version将token_dump的声明移动到get_token_type函数中。我不确切知道为什么,但如果它在类中,它们无法在该函数内找到变量。