繁体   English   中英

atoi() 等效于 intptr_t/uintptr_t

[英]atoi() equivalent for intptr_t/uintptr_t

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++ 中 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM