通过 typedef 定义 C++ 新类型
C++ new types definition via typedef
我是 C++ 的新手,我遇到了一个问题,我需要在 class 中通过 typedef 定义新的数据类型(具体来说是联合)。我的class.h模块的相关代码片段如下
class Manager
{
public:
static const uint8_t NO_BYTES_IN_PACKET;
static const uint8_t NO_PYLD_BYTES_IN_CONTROL_PACKET;
// control packet structure
typedef union{
struct{
uint8_t header[3];
uint8_t payload[NO_PYLD_BYTES_IN_CONTROL_PACKET];
}pkt_parts_t;
uint8_t pkt_array[NO_BYTES_IN_PACKET];
}control_pkt_u;
private:
}
我的问题是常量
static const uint8_t NO_BYTES_IN_PACKET;
static const uint8_t NO_PYLD_BYTES_IN_CONTROL_PACKET;
在关联的 .cpp 模块中定义
const uint8_t Manager::NO_BYTES_IN_PACKET = 8;
const uint8_t Manager::NO_PYLD_BYTES_IN_CONTROL_PACKET = 5;
因此,我一直收到一条错误消息:错误:在编译过程中,数组绑定不是“]”标记前的整数常量。我的想法是将联合定义移动到 .cpp 模块中,但我不确定这是否是正确的方法。你有什么意见?谢谢你的任何想法。
如果你没有odr-use那些static const int
,你不需要在.cc文件中定义它们,只需将值放在.h 文件:
class Manager
{
public:
static const uint8_t NO_BYTES_IN_PACKET = 8;
static const uint8_t NO_PYLD_BYTES_IN_CONTROL_PACKET = 5;
/* .... */
};
但是,如果你odr-use那些常量,比如获取它们的地址,那么你需要在.cc文件中定义它们,.h文件中的class定义保持不变:
const uint8_t Manager::NO_BYTES_IN_PACKET;
const uint8_t Manager::NO_PYLD_BYTES_IN_CONTROL_PACKET;
编辑:
对于声称 static const int
不能用作 compile-time 常量的评论或其他答案,他们的说法是错误的。
以下内容转自[class.static.data]/3(强调我的):
If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression ([expr.const]). A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. — end note ] The member shall still be defined in a namespace scope if it is odr-used ([basic.def.odr]) in the program and the namespace scope definition shall not contain an initializer.
问题是 static const
并不意味着它是一个编译时间常量。作为一个不是的例子,它可能是程序启动的时间。
你想要的是 constexpr
告诉编译器它可以在编译时计算,这意味着你的数组大小定义明确并且它传达了你的意图更清楚。
即
class Manager{
public:
constexpr uint8_t NO_BYTES_IN_PACKET = 8;
...
此外;它将迫使您解决真正的问题,即其他编译单元无法看到常量的大小,因为您没有在 header.
中定义它
我是 C++ 的新手,我遇到了一个问题,我需要在 class 中通过 typedef 定义新的数据类型(具体来说是联合)。我的class.h模块的相关代码片段如下
class Manager
{
public:
static const uint8_t NO_BYTES_IN_PACKET;
static const uint8_t NO_PYLD_BYTES_IN_CONTROL_PACKET;
// control packet structure
typedef union{
struct{
uint8_t header[3];
uint8_t payload[NO_PYLD_BYTES_IN_CONTROL_PACKET];
}pkt_parts_t;
uint8_t pkt_array[NO_BYTES_IN_PACKET];
}control_pkt_u;
private:
}
我的问题是常量
static const uint8_t NO_BYTES_IN_PACKET;
static const uint8_t NO_PYLD_BYTES_IN_CONTROL_PACKET;
在关联的 .cpp 模块中定义
const uint8_t Manager::NO_BYTES_IN_PACKET = 8;
const uint8_t Manager::NO_PYLD_BYTES_IN_CONTROL_PACKET = 5;
因此,我一直收到一条错误消息:错误:在编译过程中,数组绑定不是“]”标记前的整数常量。我的想法是将联合定义移动到 .cpp 模块中,但我不确定这是否是正确的方法。你有什么意见?谢谢你的任何想法。
如果你没有odr-use那些static const int
,你不需要在.cc文件中定义它们,只需将值放在.h 文件:
class Manager
{
public:
static const uint8_t NO_BYTES_IN_PACKET = 8;
static const uint8_t NO_PYLD_BYTES_IN_CONTROL_PACKET = 5;
/* .... */
};
但是,如果你odr-use那些常量,比如获取它们的地址,那么你需要在.cc文件中定义它们,.h文件中的class定义保持不变:
const uint8_t Manager::NO_BYTES_IN_PACKET;
const uint8_t Manager::NO_PYLD_BYTES_IN_CONTROL_PACKET;
编辑:
对于声称 static const int
不能用作 compile-time 常量的评论或其他答案,他们的说法是错误的。
以下内容转自[class.static.data]/3(强调我的):
If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression ([expr.const]). A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. — end note ] The member shall still be defined in a namespace scope if it is odr-used ([basic.def.odr]) in the program and the namespace scope definition shall not contain an initializer.
问题是 static const
并不意味着它是一个编译时间常量。作为一个不是的例子,它可能是程序启动的时间。
你想要的是 constexpr
告诉编译器它可以在编译时计算,这意味着你的数组大小定义明确并且它传达了你的意图更清楚。
即
class Manager{
public:
constexpr uint8_t NO_BYTES_IN_PACKET = 8;
...
此外;它将迫使您解决真正的问题,即其他编译单元无法看到常量的大小,因为您没有在 header.
中定义它