[英]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.