42因为unsigned int被定义为“42U”。
unsigned int foo = 42U; // yeah!
如何写“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;
}
答案 0 :(得分:35)
你做不到。数字文字不能包含short
或unsigned short
类型。
当然,为了分配给bar
,文字的值会隐式转换为unsigned short
。在您的第一个示例代码中,可以使用强制转换显式转换,但我认为已经非常明显地进行了哪些转换。转换可能更糟糕,因为对于某些编译器,如果文字值超出unsigned short
的范围,它将平息将发出的任何警告。再说一遍,如果你希望使用这样的值是有充分理由的,那么就可以解除警告了。
在编辑中的示例中,它恰好是模板函数而不是重载函数,您可以使用强制转换的替代方法:do_something<unsigned short>(23)
。使用重载函数,您仍然可以避免使用:
void (*f)(unsigned short) = &do_something;
f(23);
......但我不建议。如果没有别的,这仅在unsigned short
版本实际存在的情况下有效,而使用强制转换的调用执行通常的重载分辨率以找到最兼容的版本。
答案 1 :(得分:9)
unsigned short bar = (unsigned short) 23;
或者说新话......
unsigned short bar = static_cast<unsigned short>(23);
答案 2 :(得分:4)
至少在Visual Studio中(至少2013年和更新版本)你可以写
23ui16
获取unsigned short类型的常量。
参见stdint.h中INT8_MIN,INT8_MAX,INT16_MIN,INT16_MAX等宏的定义
我现在还不知道这是否是标准C / C ++的一部分
答案 3 :(得分:1)
没有签名短片的修饰符。默认情况下具有int
类型的整数通常隐式转换为目标类型而没有任何问题。但是如果你真的想明确指出类型,你可以写下以下内容:
unsigned short bar = static_cast<unsigned short>(23);
我可以看到唯一的原因是使用这种指示来正确推断模板类型:
func( static_cast<unsigned short>(23) );
但对于这种情况,更明确的是如下调用:
func<unsigned short>( 23 );
答案 4 :(得分:0)
不幸的是,为此定义的唯一方法是
单引号中的一个或两个字符 ('),前面是字母L
根据http://cpp.comsci.us/etymology/literals.html
这意味着您必须将您的号码表示为ASCII转义序列:
unsigned short bar = L'\x17';
答案 5 :(得分:0)
不幸的是,他们不能。但如果人们只看这个数字背后的两个字,他们应该清楚地看到它是一个简短的...它不是那么模棱两可。但这会很好。
答案 6 :(得分:0)
如果您将数量表示为4位十六进制数,则无符号的短度可能会更清晰。
unsigned short bar = 0x0017;
答案 7 :(得分:0)
你可能不应该使用短片,除非你有很多短片。它的目的是使用比int更少的存储空间,但该int将具有该体系结构的“自然大小”。从逻辑上讲,短期可能不会。与位域类似,这意味着短路可以被视为空间/时间权衡。如果它给你带来了很大的空间,那通常是值得的。但是,您的应用程序中不太可能有很多文字,因此没有必要预见短文字。用例根本没有重叠。
答案 8 :(得分:0)
这里有多个答案,但没有一个令人满意。因此,这是一个包含一些附加信息的编译答案,以帮助您更全面地解释事情。
首先,避免建议的短裤,但如果您发现自己需要诸如在处理索引网格数据时使用它们,而只是将索引大小切换为短裤,则会将索引数据大小减半...然后继续阅读...
1尽管从技术上讲,没有任何方法可以用c或C ++表示无符号的短文字,但您可以通过简单地用'u'将文字标记为无符号的方式来轻松地克服这一限制。
unsigned short myushort = 16u;
之所以起作用,是因为它告诉编译器16是unsigned int,然后编译器开始寻找一种将其转换为unsigned short的方法,然后找到一个,大多数编译器将检查是否溢出,并且在进行转换时不会产生任何抱怨。忽略“ u”时出现“变窄的转换”错误/警告是编译器抱怨代码丢掉了符号。这样,如果文字是负数(例如-1),则结果是不确定的。通常,这意味着您将获得一个非常大的无符号值,然后该值将被截断以适合short。
2关于如何克服此限制,有很多建议,大多数经验丰富的程序员都会总结为“不要那样做”。
unsigned short myshort = (unsigned short)16;
unsigned short myothershort = static_cast<unsigned short>(16);
尽管这两项工作都是不可取的,但主要有两个原因。首先,他们比较罗word,程序员变得懒惰,键入所有内容只是为了文字,很容易跳过,这会导致基本错误,而采用更好的解决方案可以避免这些错误。其次,它们不是免费的,特别是static_cast会生成一些汇编代码来进行转换,而优化器可能会(也可能不会)发现它可以更好地进行转换,以便从一开始就编写高质量的代码。 / p>
unsigned short myshort = 16ui16;
此解决方案是不受欢迎的,因为它限制了谁可以读取您的代码并理解该代码,这也意味着您正以编译器特定代码的滑坡为起点,这可能会导致您的代码突然不起作用,因为某些编译器作者或某些公司随机决定“右转”的想法,或者走开而陷入困境。
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 ++上,用户定义的运算符可以合法地完成的工作。
所以要权衡利弊,但要小心,因为稍后您可能会后悔。编程愉快。