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新的显式枚举类型。