Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;地图定义基础_C++_Map - Fatal编程技术网

C++ C++;地图定义基础

C++ C++;地图定义基础,c++,map,C++,Map,我有一个无法解决的问题。假设我有这个地图定义: map<string, int16_t> Registers; map寄存器; 但有时,我需要存储一个未签名的int16\t,而不是一个已签名的int16\t。 我该怎么做 谢谢。您必须使用能够存储您要存储的类型之一的实例的类型 存在几种方法,例如变体 一种可能性是: class Foo { public: enum class Type : char { Int16, Uint16 }; static Foo I

我有一个无法解决的问题。假设我有这个地图定义:

map<string, int16_t> Registers;
map寄存器;
但有时,我需要存储一个未签名的int16\t,而不是一个已签名的int16\t。 我该怎么做


谢谢。

您必须使用能够存储您要存储的类型之一的实例的类型

存在几种方法,例如变体

一种可能性是:

class Foo {
public:
    enum class Type : char { Int16, Uint16 };

    static Foo Int16 (int v)           { Foo ret{Type::Int16};  ret.int16_ = v; return ret;}
    static Foo Uint16 (unsigned int v) { Foo ret{Type::Uint16}; ret.uint16_ = v; return ret;}

    int16_t  as_int16()  const { assert_(Type::Int16); return int16_;  }
    uint16_t as_uint16() const { assert_(Type::Uint16); return uint16_; }

    Type type() const { return type_; }

private:
    Foo (Type type) : type_(type) {}
    void assert_(Type t) const { if (t != type_) throw "meh"; }

    union { int16_t int16_; uint16_t uint16_; };
    Type type_;
};
例如:

int main () {
    Foo f = Foo::Int16(4);
    std::cout << f.as_int16() << '\n'; // okay
    //std::cout << f.as_uint16() << '\n'; // exception

    Foo g = Foo::Uint16(4);
    std::cout << f.as_uint16() << '\n'; // okay
    //std::cout << f.as_int16() << '\n'; // exception

    // Switch on its type:
    switch (g.type())
    {
    Foo::Type::Int16: std::cout << g.as_int() << '\n'; break;
    Foo::Type::Uint16: std::cout << g.as_uint() << '\n'; break;
    }
}
int main(){
Foo f=Foo::Int16(4);

std::cout您可以使用更大的鱼型,如
int32\u t
,也可以使用
boost::variant

int32\u t
可以存储
int16\u t
uint16\u t
可以存储的所有值,并且它保留了32768和-32768之间的差异(假设两个值是互补的)。如果您将某些强制转换方案与
int16_t
uint16_t
一起使用,则两者之间的差异将丢失,因为两者都将存储为0x8000。区分0x8000之类的值将需要带外信息,如果有,您没有提及


但是,
int32\u t
不会保留32767有符号和32767无符号之间的差异。如果这很重要,那么
boost::variant
可以保留该信息。

或者引入1级间接寻址(几乎失去了存储int16的全部意义),或者您需要两个不同的映射。除非您的目标是专用硬件,或者确实需要节省空间,否则最好存储一个直接向上的int。总体而言,这将更快、更少麻烦。

鉴于这两种类型的大小相同,您可以将未签名的int转换为和int。只需确保跟踪您的值是否已签名或者unsigned,这可能意味着最好使用更大的类型,这样您就不必跟踪签名。

您是否尝试使用
uint16\u t
作为将要存储未签名整数的容器的第二个模板类型?嗨,Alexander,我不知道您可以这样做。@Alexander:您的确切意思是什么?可能给出一个声明示例?
map寄存器;
。用于异构对象(
int
&
uint
),你必须在一些自定义类中包装类型。嗨,好吧,假设我有这样一个:映射寄存器;那么如果我存储一个16位的值,它应该是无符号的,那么它有什么好处呢?我的意思是,如果我有int16\t,那么如果我知道该值是无符号的,我就强制转换它?不?我不明白使用32位的意义int@Kam-所有16位值,有符号或无符号将适合于
int32\t
。是,但所有有符号或无符号的16位值将适合于int16\talso@Kam但与32768和-32768没有明显区别(假设两个是互补的),因为两者都将存储为0x8000。区分它们需要带外知识,如果你有,你没有提到。弗雷斯内尔,我是这样一个新手,我会尝试理解你刚才写的内容并回复你。谢谢。我认为这可能会挫败询问者存储16位数字的意图。如果你努力使用16位类型,这在大多数pc平台上都是int+2的大小,因为许多枚举存储在int中。使用4字节有符号类型(在大多数地方为int/long)在很多方面都会更好。如果您使用bool来存储是否有符号,并将其重新处理为使用16位类型,则可以将每个实例的字节数减少到3个。@Sqeaky:但由于对齐,它将再次增加到4个。我将使用C++11新的显式枚举类型。