atoi() equivalent for intptr_t/uintptr_t

atoi() equivalent for intptr_t/uintptr_t

本文关键字:uintptr intptr for equivalent atoi      更新时间:2023-10-16

C++(C++11,如果有区别的话)中是否有一个函数可以将字符串转换为uintptr_tintptr_t?我总是可以使用atoll()并在之后进行强制转换,但如果能得到一个对32位机器执行32位操作、对64位机器执行64位操作的函数,那就太好了。

char* c = "1234567";
uintptr_t ptr = atoptr(c); // a function that does this;

这是国际海事组织在C++中令人惊讶的差距。虽然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);
    }

如果您决定更改句柄的类型,这将很容易更新。如果你喜欢尖括号,你也可以用模板做一些等效的事情,尽管我不知道怎么会更清楚。

最后,您还可以使用sscanf%tx格式,即

inline uintptr_t handleFromString(const char *c)
{
   ptrdiff_t h;
   sscanf(c, "%tx", &h); // only hex supported, %td for decimal.
   return (uintptr_t)h;
}

不幸的是,我在编译器资源管理器上尝试的任何编译器都无法以删除对sscanf调用的方式优化代码。