我有一个值可以采用以下语义值之一(它们在上下文之外没有意义,但确切的上下文并不重要):
- 仅应要求
- 仅限事件
- Automatic With Interval N(其中 N 是 1 到 200 之间的整数)
在内部,所有这些都由一个整数表示:
- 仅请求 = 0
- 仅限事件 = 252
- Automatic With Interval N = N(其中 N 是从 1 到 200)
我想用一个名为 MessageType
的类型来表示这个值,我想把这个值传递给一个函数 setMessageType()
,两者都是一个类的成员:
class Example {
public:
// <= definition of MessageType would be here.
...
void setMessageType (int id, MessageType type);
};
我希望此类型满足以下要求:
- 它的用法很清楚(例如名为
ByRequestOnly
和OnEventOnly
的常量)。 - “automatic with interval”的用法很明确并且强制N在运行时在适当的范围内,(例如
自动 (50)
). - 重要的是,使用这种类型的开发人员不能无意中传递一个不想要的值(奇怪的抛弃);也就是说,我想要
enum
提供的相同级别的编译时语义,但“自动”值范围的运行时验证除外。 - 给定
int
,“automatic with interval”值应该可以方便地构造。
换句话说,我希望能够编写如下所示的代码:
Example example;
example.setMessageType(0, Example::ByRequestOnly);
example.setMessageType(0, Example::OnEventOnly);
example.setMessageType(0, Example::Automatic(1));
example.setMessageType(0, Example::Automatic(200));
int n = ...; // from 1 to 200
example.setMessageType(0, Example::Automatic(n));
example.setMessageType(0, Example::Automatic(500)); // <= throws exception
在 setMessageType()
中,我需要将值转换为其内部表示:
void Example::setMessageType (int id, MessageType type) {
int internal = type.internalValue(); // e.g. 252 for OnEventOnly
...
}
我很难定义满足上述所有要求的类型。一种可能性是只使用等于内部表示的整数类型:
class Example {
public:
typedef int MessageType;
static const int ByRequestOnly = 0;
static const int OnEventOnly = 252;
// use integer value 1-200 for interval
};
问题:任何 int
都可以在没有语义的情况下使用。没有完成自动间隔设置的验证。
我还尝试使用一个混合了常量值和静态函数的 struct
:
class Example {
public:
struct MessageType {
friend class Example;
private:
explicit MessageType (int iv) : internalValue_(iv) { }
int internalValue_;
};
static const MessageType ByRequestOnly = MessageType(0);
static const MessageType OnEventOnly = MessageType(252);
static MessageType Automatic (int interval) {
if (interval >= 1 && interval <= 200)
return MessageType(interval);
else
throw runtime_error("Invalid automatic interval.");
}
};
问题:这无法编译,因为构造函数不能用于常量表达式。
我可以做的另一件事是使用一个巨大的枚举:
class Example {
public:
enum MessageType {
ByRequestOnly = 0,
OnEventOnly = 252,
Automatic_1 = 1,
Automatic_2 = 2,
Automatic_3 = 3,
...,
Automatic_200 = 200
};
};
但这非常麻烦,无论是实现,尤其是将 int
转换为“自动”的这些值之一(自动值的运行时检查将在转换的实现中完成枚举的一个整数)。
我该怎么做?我如何定义某种类型,使我在编译时具有与 enum
类似的行为,同时又允许某些值的“动态”范围,并对这些情况进行运行时检查?
最佳答案
如果将静态常量的初始化放在源文件中而不是头文件中,您的Example
类将会编译。
class Example {
public:
struct MessageType {
friend class Example;
private:
explicit MessageType (int iv) : internalValue_(iv) { }
int internalValue_;
};
static const MessageType ByRequestOnly;
static const MessageType OnEventOnly;
static MessageType Automatic (int interval) {
if (interval >= 1 && interval <= 200)
return MessageType(interval);
else
throw runtime_error("Invalid automatic interval.");
}
};
在cpp文件的其他地方
const Example::MessageType Example::ByRequestOnly = Example::MessageType(0);
const Example::MessageType Example::OnEventOnly = Example::MessageType(252);
关于c++ - 常量和 "dynamic"选项值的混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23095591/