ICMPヘッダーをポッドタイプとして定義したい:
struct ICMPHeader
{
    uint8_t   Type;         // ICMP type
    uint8_t   Code;         // Subtype, value is dependent on ICMP type.
    uint16_t  Checksum;     // Error checking data. See RFC 1071
    uint32_t  RestOfHeader; // Varies based on ICMP type and code.
};
フィールドでは、ICMPType強く型付けされた列挙型を使用して、少し見栄えを良くすることができます。
enum class ICMPType : uint8_t
{
    EchoReply              = 0,
    Reserved1              = 1,
    Reserved2              = 2,
    DestinationUnreachable = 3,
    SourceQuench           = 4
    // etc...
};
struct ICMPHeader
{
    ICMPType  Type;         // ICMP type
    uint8_t   Code;         // Subtype, value is dependent on ICMP type.
    uint16_t  Checksum;     // Error checking data. See RFC 1071
    uint32_t  RestOfHeader; // Varies based on ICMP type and code.
};
Codeさて、当然、フィールドを列挙型として指定したいと思います。テンプレートの特殊化構文を使用できればいいのですが、簡単なテストで機能しないことがわかります。
// Compiler error
template<ICMPType>
enum class ICMPCode;    
template<>
enum class ICMPCode<ICMPType::DestinationUnreachable>
{
    DestinationNetworkUnreachable  = 0,
    DestinationHostUnreachable     = 1,
    DestinationProtocolUnreachable = 2
};
1つのオプションは、それらを構造体でラップすることです。
// Meaning of ICMP code is dependent on ICMP type.
template<ICMPType>
struct ICMPCode;
// Subcodes for DestinationUnreachable
template<> struct ICMPCode<ICMPType::DestinationUnreachable>
{
    enum class Code : uint8_t
    {
        DestinationNetworkUnreachable  = 0,
        DestinationHostUnreachable     = 1,
        DestinationProtocolUnreachable = 2
        // etc...
    };
};
// Access: ICMPCode<ICMPType::DestinationUnreachable>::Code::DestinationHostUnreachable
しかし、このようにすると、私はただいじり回して、物事を複雑にしすぎているように感じます。
これは、より一般的な質問の具体例だと思います。タイプとサブタイプのシステムをセットアップする方法は?助言がありますか?
追伸:
サンプルコード:
#include <iostream>
// Trying to model ICMP types and codes with strongly typed enums
// See also http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol#Header
enum class ICMPType : uint8_t
{
    EchoReply              = 0,
    Reserved1              = 1,
    Reserved2              = 2,
    DestinationUnreachable = 3,
    SourceQuench           = 4
    // etc...
};
// Meaning of ICMP code is dependent on ICMP type.
template<ICMPType>
struct ICMPCode;
// Subcodes for DestinationUnreachable
template<> struct ICMPCode<ICMPType::DestinationUnreachable>
{
    enum class Code : uint8_t
    {
        DestinationNetworkUnreachable  = 0,
        DestinationHostUnreachable     = 1,
        DestinationProtocolUnreachable = 2
        // etc...
    };
};
ICMPCode<ICMPType::DestinationUnreachable>::Code GetReasonWhyDestinationIsUnreachable()
{
    return ICMPCode<ICMPType::DestinationUnreachable>::Code::DestinationHostUnreachable;
}
int main()
{
    std::cout << static_cast<int>(GetReasonWhyDestinationIsUnreachable()) << std::endl;
}