代码之家  ›  专栏  ›  技术社区  ›  LukeN

包装这个空指针的最佳方法是什么?

  •  1
  • LukeN  · 技术社区  · 14 年前

    typedef struct nbt_tag
    {
        nbt_type type; /* Type of the value */
        char *name;    /* tag name */
    
        void *value;   /* value to be casted to the corresponding type */
    
    } nbt_tag;
    
    int64_t *nbt_cast_long(nbt_tag *t)
    {
        if (t->type != TAG_LONG) return NULL;
    
        return (int64_t *)t->value;
    }
    

    char ),短标签( int16_t ),标记\u INT( int32_t int64_t ),标记\u浮动( float double ),标记\u字符串( char * )还有一些稍微复杂一些的数据类型,TAG\u List( struct nbt_list ),TAG\复合物( struct nbt_compound ),标记字节数组( struct nbt_byte_array ).

    我现在试图把这个映射到C++中,但是我不能完成它。

    char getByte();                     // TAG_BYTE
    int16_t getShort();                 // TAG_SHORT
    int32_t getInt();                   // TAG_INT
    int64_t getLong();                  // TAG_LONG
    float getFloat();                   // TAG_FLOAT
    double getDouble();                 // TAG_DOUBLE
    std::string getString();            // TAG_STRING
    std::vector<char> getByteArray();   // TAG_BYTE_ARRAY
    std::vector<Tag> getCompound();     // TAG_COMPOUND
    

    5 回复  |  直到 14 年前
        1
  •  3
  •   Alexandre C.    14 年前

    template <int> struct TypeTag {};
    template <> struct TypeTag<TAG_BYTE> { typedef char type; };
    // ...
    template <> struct TypeTag<TAG_COMPOUND> { typedef vector<Tag> type; };
    
    template <int tag>
    typename TypeTag<tag>::type getValue(nbt_tab* t)
    {
        if (t->type != tag) ... // throw an exception
        return *reinterpret_cast<typename TypeTag<tag>::type*>(t-value);
    }
    

    像这样使用:

    char x = getValue<TAG_BYTE>(t);
    vector<Tag> v = getValue<TAG_COMPOUND>(t);
    

    template <>
    vector<Tag> getValue<TAG_COMPOUND>(nbt_tab* t)
    {
        if (t->type != TAG_COMPOUND) ... // throw something
        vector<Tag> ans(/* size */); // [rely on named return value optimization]
    
        // Fill the vector with your data
    
        return ans; // [Pray for the copy constructor not to get called]
    }
    
        2
  •  0
  •   Paul    14 年前

    你可以为函数做模板。

    template <typename T>
    typename T get();
    
        3
  •  0
  •   Nick    14 年前

    这并不是一个直接的答案,但是看看VARIANT(在Windows中),以及相应的CComVariant和VARIANT包装器类:这基本上做了相同的事情,您可能能够从那里得到一些细节。

        4
  •  0
  •   TheUndeadFish    14 年前

    当然也有一些方法可以使用模板巫毒来将其简化为一个 get<X>() 函数(可能有一些专门化)。但在这里,你要权衡写这些东西的简单性 getX

    如果支持的不同类型的数量永远不会(或者很少)改变,那么最简单和最容易理解的可能就是那些不同的类型 getX公司

        5
  •  0
  •   Puppy    14 年前

    您可以使用boost::variant。此类型可以存储它的任何模板参数,并且可以查询它所包含的参数。只需在一个向量中保存一堆,然后返回对您最喜欢的变体的引用。