C++ 如何编写无符号短整型文字?

C++ 如何编写无符号短整型文字?,c++,types,C++,Types,42 as unsigned int定义为“42U” 如何写入“23”以便清楚地知道它是一个无符号的短整数? unsigned short bar = 23; // booh! not clear! 编辑以使问题的含义更清楚: template <class T> void doSomething(T) { std::cout << "unknown type" << std::endl; } template<> void doSo

42 as unsigned int定义为“42U”

如何写入“23”以便清楚地知道它是一个无符号的短整数?

unsigned short bar = 23; // booh! not clear!

编辑以使问题的含义更清楚:

template <class T>
void doSomething(T) {
    std::cout << "unknown type" << std::endl;
}

template<>
void doSomething(unsigned int) {
    std::cout << "unsigned int" << std::endl;
}

template<>
void doSomething(unsigned short) {
    std::cout << "unsigned short" << std::endl;
}

int main(int argc, char* argv[])
{
    doSomething(42U);
    doSomething((unsigned short)23); // no other option than a cast?

    return EXIT_SUCCESS;
}
模板
无效剂量测定法(T){

std::cout不能。数字文本不能具有
short
无符号short
类型

当然,为了分配给
,文本的值被隐式转换为
无符号短
。在您的第一个示例代码中,您可以通过强制转换使转换显式化,但我认为已经很明显会发生什么转换。强制转换可能更糟糕,因为在某些编译器中,它将l如果文字值超出
无符号短字符
的范围,将发出任何警告。然后,如果您想出于正当理由使用此值,则消除警告是好的

在编辑中的示例中,它恰好是一个模板函数而不是重载函数,您确实有一个替代强制转换的选项:
do\u something(23)
。对于重载函数,您仍然可以通过以下方式避免强制转换:

void (*f)(unsigned short) = &do_something;
f(23);

…但我不建议这样做。如果没有其他建议,这只适用于
无符号short
版本实际存在的情况,而使用cast的调用执行通常的重载解析,以找到可用的最兼容版本。

不幸的是,为此定义的唯一方法是

单引号中的一个或两个字符 ('),前面是字母L

这意味着您必须将数字表示为ASCII转义序列:

unsigned short bar = L'\x17';

不幸的是,他们不能。但是如果人们只看数字后面的两个单词,他们应该清楚地看到它是一个短字符……它没有那么模糊。但这会很好。

如果你将数量表示为4位十六进制数,则无符号的短字符可能更清晰

无符号短条=0x0017;

unsigned short bar = (unsigned short) 23;
或者换个说法

unsigned short bar = static_cast<unsigned short>(23);
unsigned short bar=static_cast(23);

无符号短整数没有修饰符。默认情况下,整数的类型为
int
type,通常隐式转换为目标类型,不会出现任何问题。但如果确实要显式指示类型,可以编写以下代码:

unsigned short bar = static_cast<unsigned short>(23);
func<unsigned short>( 23 );
unsigned short bar=static_cast(23);
如我所见,唯一的原因是使用此类指示来正确推断模板类型:

func( static_cast<unsigned short>(23) );
func(static_cast(23));
但对于这种情况,更明确的要求如下:

unsigned short bar = static_cast<unsigned short>(23);
func<unsigned short>( 23 );
func(23);

除非你有很多short,否则你可能不应该使用short。short的目的是使用比int更少的存储空间,但int将具有“自然大小”对于体系结构而言。从逻辑上讲,short可能不会。与位字段类似,这意味着short可以被视为一种空间/时间权衡。这通常只有在它为您购买了大量空间的情况下才值得。不过,您的应用程序中不太可能有很多文本,因此没有必要使用short-literals.用例没有重叠。

至少在VisualStudio(至少2013年及更新版本)中,您可以编写

23ui16
获取类型为unsigned short的常量

请参阅stdint.h中的INT8_MIN、INT8_MAX、INT16_MIN、INT16_MAX等宏的定义


我现在不知道这是否是标准C/C++的一部分,这里有多个答案,没有一个非常令人满意。因此,这里有一个编译答案,添加了一些信息,以帮助更全面地解释问题

首先,按照建议避免使用短裤,但如果您发现自己需要短裤,例如在处理索引网格数据时,简单地切换到短裤以获得索引大小,会将索引数据大小减半…然后继续阅读

<> 1,虽然在技术上是正确的,在C或C++中没有表示短符号的字面,但是你可以很容易地把这个字面标记成没有符号的“u”。
unsigned short myushort = 16u;
这是因为它告诉编译器16是unsigned int,然后编译器会寻找一种方法将其转换为unsigned short,找到一个,大多数编译器会检查溢出,并毫无怨言地进行转换。“缩小转换”错误/警告被忽略的是编译器抱怨代码丢弃了符号。因此,如果文本为负数,如-1,则结果未定义。通常这意味着您将得到一个非常大的无符号值,然后将截断该值以适应短值

2关于如何避开这一限制有多种建议,大多数经验丰富的程序员都会用“不要那样做”来总结

这种解决方案是不可取的,因为它限制了谁可以阅读和理解您的代码,它还意味着您正在沿着特定于编译器的代码的滑坡开始,这可能会导致您的代码突然无法工作,因为某些编译器编写者的突发奇想,或者一些随机决定“右转”的公司,或是离开,在你身上留下一片狼藉

unsigned short bar = L'\x17';
这是如此不可读,以至于没有人对它投赞成票。出于许多好的理由,不可读应该被避免

unsigned short bar = 0xf;
这是不可读的。虽然能够读取、理解和转换十六进制是严肃的程序员真正需要学习的东西,但它非常不可读。这是什么数字:0xbad;现在将它转换为二进制…现在是八进制

3最后,如果您发现上述所有解决方案都不可取,我将提供另一个通过用户定义的操作员提供的解决方案

constexpr unsigned short operator ""_ushort(unsigned long long x) 
{ 
    return (unsigned short)x; 
}
以及如何使用它

unsigned short x = 16_ushort;
诚然,这也不是完美的。首先,它需要一个无符号的long-long,然后一路向下打击到一个无符号的short,从而抑制潜在的编译器警告,并且它使用c风格的强制转换。但是,是constexpr保证了它在优化程序中是免费的,而c
unsigned short x = 16_ushort;