![](/img/trans.png)
[英]How to create an std::function as method argument with std::stoi as default value?
[英]How is std::stoi implemented?
大多數日常用例已經轉換為標准庫中可用的函數。 但是,我想知道其中一些是如何在幕后工作的。 比如std::stoi
背后的實際代碼是什么?
最直接的方法是調用適當的 C 函數,在本例中為strtol
,檢查發生了什么,如果失敗則拋出適當的異常,然后返回結果。
我想知道他們中的一些人是如何在幕后工作的。 就像 std::stoi 背后的實際代碼是什么?
我認為您可以通過類似以下的搜索找到“實際”代碼:
在 Ubuntu 上,我的 makefile 創建了一個 .depends 文件,其中包含:
g++-5 -m64 -O3 -ggdb -std=c++14 -Wall -Wextra -Wshadow -Wnon- virtual-dtor -pedantic -Wcast-align -Wcast-qual -Wconversion -Wpointer-arith -Wunused -Woverloaded-virtual -O0 -M *.cc > .depends
(我嘗試使該命令的編譯器選項與我的正常編譯相匹配。)
在瀏覽器中,我查看
http://en.cppreference.com/w/cpp/string/basic_string/stol
確定
std::stoi 包含在 std::basic_string 中(在頁面頂部)
在我的編輯器中,(或)使用 grep,我在 .depends 文件中搜索“basic_string”
grep --color -nH -e "basic_string" .depends
grep 在我當前的依賴文件中報告字符串 214 次,當我更改代碼時它會改變大小。
一份報告的例子:
.depends:14105: /usr/include/c++/5/bits/basic_string.h \
在我的編輯器中,我打開指定的文件
"/usr/include/c++/5/bits/basic_string.h",
然后搜索“stoi”,它似乎只存在兩次。
這表示編譯器的 v5。
我認為您應該能夠在您的系統上進行類似的搜索。
祝你好運。
它是對strtoi
的引用,但我假設您想要一個關於它如何工作的實際解釋。 其實很簡單。 腳步:
strtoi
在 C 中的實現:
#include <string.h>
int ipow(int base, int exp)
{
int result = 1;
for (;;)
{
if (exp & 1)
result *= base;
exp >>= 1;
if (!exp)
break;
base *= base;
}
return result;
}
int charToDigit(char ch) {
switch (ch) {
case '0':
return 0;
break;
case '1':
return 1;
break;
case '2':
return 2;
break;
case '3':
return 3;
break;
case '4':
return 4;
break;
case '5':
return 5;
break;
case '6':
return 6;
break;
case '7':
return 7;
break;
case '8':
return 8;
break;
case '9':
return 9;
break;
default:
throw "0-9";
break;
}
};
int stoi(const char* string) {
int basenum = 0;
int pos = ipow(10, strlen(string)-1);
const int len = strlen(string);
// first is biggest, pos
for (int i = 0; i<len; i++) {
basenum += charToDigit(string[i])*pos;
pos /= 10;
};
return basenum;
};
要轉換一個字符串(假設它的所有字符都是從 0 到 9 的整數):
我將從一個乘數變量和一個結果變量開始: int multiplier = 1, result = 0
,然后我將使用std::string::length
函數獲取字符串長度。 通過字符串向后循環,我會將每個元素乘以乘數並將其添加到結果中。 請確保當您訪問 char 時,您應該減去 char 0 的 ASCII 值。這可以通過減去 48 來完成,或者如果您不想查找 ASCII 值,您可以將 0 包含在單個括號。 例如,如果您不執行從 char 到 int 的轉換,那么訪問字符“1”將導致程序讀取 49,這是不好的。 至於乘數,在循環的每次迭代結束時將其乘以 10。
我從后面迭代的原因是為了避免使用使用 double/float 的 pow() 函數。 我覺得它更簡單,但這是你的選擇。 當然,您也可以通過手動循環乘以 10 與字符串長度相同的次數來避免 pow(),但這樣效率會低一些。
這是一個可以使用的簡單實現:
#include <string>
#include <iostream>
int stoi(std::string s) {
int multiplier = 1, result = 0;
for (int i = s.length() - 1; i >= 0; i--) {
result += multiplier * (s[i] - '0');
multiplier *= 10;
}
return result;
}
int main() {
std::cout << stoi("1235") + 1;
return 0;
}
如果你運行這個程序,它應該輸出 1236,因為字符串“1235”已經被轉換成一個整數。
當然,這只是我自己的實現; 如果您想要官方的,那么本文包含一些相關信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.