[英]atoi() equivalent for intptr_t/uintptr_t
C++(C++11,如果有区别)中是否有一个函数可以将字符串转换为uintptr_t
或intptr_t
? 我总是可以使用atoll()
并在之后进行转换,但是如果能得到一个在 32 位机器上执行 32 位而在 64 位机器上执行 64 位的函数会很好。
char* c = "1234567";
uintptr_t ptr = atoptr(c); // a function that does this;
这是 C++ 中 IMO 令人惊讶的差距。 虽然stringstream
完成这项工作,但对于如此简单的任务来说,它是一个相当沉重的工具。 相反,您可以编写一个内联函数,根据类型大小调用strtoul
的正确变体。 由于编译器知道正确的大小,因此可以很聪明地将对该函数的调用替换为对 strtoul 或 strtoull 的调用。 即,类似于以下内容:
inline uintptr_t handleFromString(const char *c, int base = 16)
{
// See if this function catches all possibilities.
// If it doesn't, the function would have to be amended
// whenever you add a combination of architecture and
// compiler that is not yet addressed.
static_assert(sizeof(uintptr_t) == sizeof(unsigned long)
|| sizeof(uintptr_t) == sizeof(unsigned long long),
"Please add string to handle conversion for this architecture.");
// Now choose the correct function ...
if (sizeof(uintptr_t) == sizeof(unsigned long)) {
return strtoul(c, nullptr, base);
}
// All other options exhausted, sizeof(uintptr_t) == sizeof(unsigned long long))
return strtoull(c, nullptr, base);
}
如果您决定更改手柄的类型,这将很容易更新。 如果你喜欢尖括号,你也可以用模板做一些等效的事情,尽管我看不出这会更清楚。
最后,您还可以使用%tx
格式的sscanf
,即
inline uintptr_t handleFromString(const char *c)
{
ptrdiff_t h;
sscanf(c, "%tx", &h); // only hex supported, %td for decimal.
return (uintptr_t)h;
}
不幸的是,我在 Compiler Explorer 上尝试过的编译器都没有设法以删除对 sscanf 调用的方式优化代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.