提问人:StckXchnge-nub12 提问时间:11/7/2023 最后编辑:StckXchnge-nub12 更新时间:11/7/2023 访问量:140
如何将任意 std::integral 类型转换为无符号?
How to cast an arbitrary std::integral type to unsigned?
问:
当设置特殊标志时,我试图将 std::integral 类型转换为无符号,即在这种情况下,它应该简单地解释为无符号数字。在这种情况下,这种强制转换是必要的,因为以后需要将数字作为无符号传递给另一个不受我控制的函数。但是,我找不到成功编译的解决方案。
这是一个最有前途的解决方案(我从 https://stackoverflow.com/a/33049554 那里拿来的):
#include <concepts>
#include <type_traits>
#include <iostream>
bool change = true;
void do_something(const std::floating_point auto num) {
// Do something else
std::cout << "Got floating num: " << num;
return;
}
void do_something(const std::integral auto num) {
if (change) {
// Interpret as unsigned
std::make_unsigned<decltype(num)>::type unsigned_num = num; // FAILS
std::cout << "Got integral and changed to unsigned: " << unsigned_num;
} else {
// Do something else
std::cout << "Got integral and keeping as is: " << num;
return;
}
}
int main() {
do_something(1);
do_something(-1);
do_something(0.5);
change = false;
do_something(1);
do_something(-1);
do_something(0.5);
}
(使用 g++ --std=c++20 编译)
编译器错误消息:
mwe.cc:7:30: error: ‘floating_point’ in namespace ‘std’ does not name a type; did you mean ‘is_floating_point’?
7 | void do_something(const std::floating_point auto num) {
| ^~~~~~~~~~~~~~
| is_floating_point
mwe.cc:7:45: error: expected ‘,’ or ‘...’ before ‘auto’
7 | void do_something(const std::floating_point auto num) {
| ^~~~
mwe.cc: In function ‘void do_something(int)’:
mwe.cc:9:46: error: ‘num’ was not declared in this scope; did you mean ‘enum’?
9 | std::cout << "Got floating num: " << num;
| ^~~
| enum
mwe.cc: At global scope:
mwe.cc:13:30: error: ‘integral’ in namespace ‘std’ does not name a type; did you mean ‘internal’?
13 | void do_something(const std::integral auto num) {
| ^~~~~~~~
| internal
mwe.cc:13:39: error: expected ‘,’ or ‘...’ before ‘auto’
13 | void do_something(const std::integral auto num) {
| ^~~~
mwe.cc:13:6: error: redefinition of ‘void do_something(int)’
13 | void do_something(const std::integral auto num) {
| ^~~~~~~~~~~~
mwe.cc:7:6: note: ‘void do_something(int)’ previously defined here
7 | void do_something(const std::floating_point auto num) {
| ^~~~~~~~~~~~
mwe.cc: In function ‘void do_something(int)’:
mwe.cc:16:45: error: ‘num’ was not declared in this scope; did you mean ‘enum’?
16 | std::make_unsigned<decltype(num)>::type unsigned_num = num;
| ^~~
| enum
mwe.cc:16:49: error: template argument 1 is invalid
16 | std::make_unsigned<decltype(num)>::type unsigned_num = num;
| ^
mwe.cc:16:57: error: expected initializer before ‘unsigned_num’
16 | std::make_unsigned<decltype(num)>::type unsigned_num = num;
| ^~~~~~~~~~~~
mwe.cc:17:74: error: ‘unsigned_num’ was not declared in this scope; did you mean ‘unsigned’?
17 | std::cout << "Got integral and changed to unsigned: " << unsigned_num;
| ^~~~~~~~~~~~
| unsigned
mwe.cc:20:68: error: ‘num’ was not declared in this scope; did you mean ‘enum’?
20 | std::cout << "Got integral and keeping as is: " << num;
| ^~~
| enum
是什么导致了这些问题,您建议如何克服这些问题?
答:
0赞
gera verbun
11/7/2023
#1
根据文档,您应该按照以下示例中的操作:make_unsigned
也就是说,对于您的示例:
using unsigned_num_t = std::make_unsigned_t<decltype(num)>;
const unsigned_num_t unsigned_num = num;
或者正如你被告知的那样,你应该只添加 typename,如下所示:
typename std::make_unsigned<decltype(num)>::type unsigned_num = num;
下一个:如何计算两个无符号整数的绝对差?
评论
typename
std::make_signed_t
type