c++ - 常量和 "dynamic"选项值的混合

标签 c++

我有一个值可以采用以下语义值之一(它们在上下文之外没有意义,但确切的上下文并不重要):

  • 仅应要求
  • 仅限事件
  • 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);
};

我希望此类型满足以下要求:

  • 它的用法很清楚(例如名为 ByRequestOnlyOnEventOnly 的常量)。
  • “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/

相关文章:

c++ - 在 C++ 中将 typedef 函数从头文件实现到源文件中

c++ - strcmp 错误 'WCHAR [260]' 到 'const char *'

c++ - 只允许传递指向新对象的指针

c++ - 只要使用 ctypes 的 long 被截断,Python 整数就会传递给 C++ 函数

c++ - 使用 C API 覆盖 Lua 中的赋值运算符

c++ - 在 hackerrank 生日蛋糕蜡烛问题中使用 std::vector

c++ - 带 GDI 的黑色高亮条

c++ - VC++ 使用 fp :fast causes wrong (not just inaccurate) results - is this a compiler bug?

c++ - 如何区分 C++11 中的填充构造函数和范围构造函数?

c++ - 成员包含其他继承类的继承类?