我有一个带有在公共部分声明的枚举的C ++头文件:
enum Button {A, B, C, D};
使用该枚举作为私有部分中的模板参数的地图:
map<Button, int> bindings;
如果不是因为我喜欢在公共部分之前定义私有部分,那么这将完美地工作,因此编译器不会将Button识别为符号。我已经在地图声明工作之前检查并移动了Button声明。
这对我来说似乎是一个巨大的限制,我是否可以使用解决方法而无需翻转我的头文件的公共和私有部分?
答案 0 :(得分:5)
你可以在C ++ 11中使用。
您不能只是向前声明枚举,因为编译器需要先知道枚举的大小才能使用枚举,枚举的大小取决于枚举的大小和值。
C ++ 11添加了新的语法,允许您告诉编译器枚举的大小:
enum <name> : <underlying_type>
所以你可以把你的课写成:
class Foo
{
public:
enum Button : char;
private:
map<Button, int> bindings;
public:
enum Button : char
{
A,
B,
C,
D
};
};
但是,你仍然无法从公共部分获得前瞻声明。但是定义可以在地图声明之后出现。
答案 1 :(得分:3)
两个解决方案(都需要C ++ 11):
class S {
public:
enum class Button;
private:
std::map<Button, int> bindings;
public:
enum class Button {A, B, C, D};
};
或者:
class S {
public:
enum Button : int;
private:
std::map<Button, int> bindings;
public:
enum Button : int {A, B, C, D};
};
答案 2 :(得分:1)
使用枚举类或为枚举指定默认类型,然后您可以转发声明它。
E.g:
enum class Button;
但是,这个前瞻声明必须在私人部分。
顺便说一下private
之前public
非常奇怪。其他人使用的公共接口不应该在顶部吗?
答案 3 :(得分:0)
虽然我认为这可能是一个坏主意,但这是实现这一目标的一种方式,实际上确实可以避免甚至向你班级的任何公众成员发出前瞻声明:
class MyClass;
class MyClassPublic;
template <typename> class MyClassPrivate;
template <typename TPublic = MyClassPublic>
class MyClassPrivate : public TPublic
{
map<typename TPublic::Button, int> bindings;
};
class MyClassPublic
{
public:
enum Button { A, B, C, D };
};
class MyClass : public MyClassPrivate<>
{
};
它依赖于模板类分两个阶段处理的事实,一次是在模板定义时,一次是在模板实例化时。在模板定义时,允许对尚未定义的成员进行一些引用。