我是C ++的新手,我遇到了一个问题,我需要通过类中的typedef定义一个新的数据类型(具体的联合)。我班的.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模块中,但我不确定它是否是正确的方法。你有什么看法?谢谢你的任何想法。
答案 0 :(得分:2)
如果你没有使用那些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;
/* .... */
};
但是,如果你使用这些常量,比如使用它们的地址,那么你需要在.cc文件中定义它们,.h文件中的类定义保持不变:
const uint8_t Manager::NO_BYTES_IN_PACKET;
const uint8_t Manager::NO_PYLD_BYTES_IN_CONTROL_PACKET;
修改强>:
对于声称static const int
无法用作编译时常量的评论或其他答案,他们的说法是错误的。
以下引自[class.static.data]/3(强调我的):
如果非易失性const静态数据成员是整数类型或枚举类型,则其在类定义中的声明可以指定一个大括号或大小为初始化器,其中作为赋值表达式的每个initializer子句都是一个常量表达式([expr.const])。可以使用constexpr说明符在类定义中声明文字类型的静态数据成员;如果是这样,它的声明应指定一个大括号或等于初始化器,其中作为赋值表达式的每个initializer子句都是一个常量表达式。 [注意:在这两种情况下,成员可能会出现在常量表达式中。 - 结束注释] 如果成员使用了odr,则仍应在命名空间范围内定义程序中的([basic.def.odr])和命名空间范围定义不应包含初始化程序。
答案 1 :(得分:1)
问题在于static const
并不意味着它是编译时常量。作为一个例子,它可能是程序开始的时间。
你想要的是constexpr
告诉编译器它可以在编译器时计算,这意味着你的数组大小定义得很好,它可以更清楚地传达你的意图。
即
class Manager{
public:
constexpr uint8_t NO_BYTES_IN_PACKET = 8;
...
另外;它将迫使你解决真正的问题,即其他编译单元无法看到常量的大小,因为你没有在标题中定义它。