Di pustaka standar C ++ ada fungsi untuk mengkonversi dari string ke tipe numerik:
stoi
stol
stoll
stoul
stoull
stof
stod
stold
tapi saya merasa membosankan untuk menggunakannya dalam kode templat. Mengapa tidak ada fungsi template seperti:
template<typename T>
T sto(...)
untuk mengubah string ke tipe numerik?
Saya tidak melihat alasan teknis untuk tidak memilikinya, tetapi mungkin saya kehilangan sesuatu. Mereka dapat dikhususkan untuk memanggil fungsi-fungsi bernama yang mendasari dan menggunakan enable_if
/ concepts
untuk menonaktifkan tipe non numerik.
Apakah ada alternatif ramah template di perpustakaan standar untuk mengkonversi string ke tipe numerik dan sebaliknya dengan cara yang efisien?
c++
string-conversion
Mircea Ispas
sumber
sumber
Jawaban:
C ++ 17 memiliki fungsi string to number yang umum, tetapi dinamai secara berbeda. Mereka pergi
std::from_chars
, yang kelebihan beban untuk semua jenis numerik.Seperti yang Anda lihat, overload pertama adalah mengambil semua tipe integer sebagai parameter output dan akan memberikan nilai kepadanya jika memungkinkan.
Dapat digunakan seperti ini:
Seperti yang Anda lihat, ini dapat bekerja dalam konteks umum.
sumber
Ini bukan templat, dan tidak berfungsi dengan lokal tetapi jika itu bukan penghenti acara, maka C ++ 17 sudah memiliki yang Anda inginkan:
std::from_chars
Ada kelebihan untuk semua tipe integer dan floating-point dan antarmuka adalah sama kecuali untuk parameter terakhir yang berbeda untuk tipe integer dan floating-point masing-masing (tetapi jika defaultnya baik-baik saja maka Anda tidak perlu ubah apapun). Karena ini bukan fungsi sadar-lokal, ia juga cukup cepat. Ini akan mengalahkan salah satu dari string lain untuk menilai fungsi konversi dan umumnya dengan perintah besarnya.
Ada video CPPCON yang sangat bagus tentang
<charconv>
( tandanya kepalafrom_chars
) oleh Stephan T. Lavavej yang dapat Anda tonton tentang penggunaan dan kinerjanya di sini: https://www.youtube.com/watch?v=4P_kbF0EbZMsumber
stoi
dan teman-temannya (konversi yang disebutkan dalam pertanyaan) juga tidak berfungsi dengan lokal, jadi itu bukan showstopper.Anda tidak akan mendapatkan banyak karena dalam ekspresi suka
Tidak ada cara (mudah) untuk menyimpulkan tipe yang diinginkan untuk parameter template. Anda harus menulis
yang untuk beberapa memperpanjang kekalahan tujuan menyediakan fungsi generik. Di sisi lain, a
akan bermanfaat jika Anda menyadari. Di C ++ 17 ada
std::from_chars
, yang melakukan lebih atau kurang persis itu (itu bukan template tapi satu set kelebihan dan dibutuhkan pointer ke karakter bukan string, tapi itu hanya detail kecil).PS Tidak ada cara mudah untuk menyimpulkan jenis yang diinginkan dalam ekspresi di atas, tetapi ada cara. Saya tidak berpikir inti dari pertanyaan Anda persis tanda tangan yang Anda minta, dan saya tidak berpikir berikut ini adalah cara yang baik untuk mengimplementasikannya, tetapi saya tahu bahwa ada cara untuk membuat
int x = sto("1");
kompilasi di atas dan saya ingin melihatnya dalam aksi.Ini berfungsi sebagaimana dimaksud, tetapi memiliki kelemahan parah, mungkin yang paling penting itu memungkinkan untuk menulis
auto x = sto(s);
, yaitu mudah digunakan salah.sumber
auto x = sto(s)
? Implementasi khusus ini rusak karenaconverter::x
merupakan referensi yang keluar dari ruang lingkup, tapi itu bisa diperbaiki. Hapus saja referensi dan andalkanstd::string
semantik bergerak.converter
, juga saya tidak yakin apakah menggunakan operator konversi template adalah pilihan terbaik, hal-hal yang dapat diperbaiki. Mungkin itu tidak seburuk yang saya pikir sebelumnyaSolusi yang kompatibel dengan semua (bahkan kompiler C ++ yang lebih tua seperti C ++ - 98 yang) adalah dengan menggunakan boost :: lexical_cast yang merupakan template untuk mengkonversi antara tipe numerik dan tipe string dalam kedua cara.
Contoh:
Lihat: https://www.boost.org/doc/libs/1_42_0/libs/conversion/lexical_cast.htm
sumber
Pada versi C ++ yang lebih lama, stringstream adalah teman Anda. Jika saya mengerti dengan benar, maka hal berikut ini mungkin menarik bagi Anda. Ini adalah C ++ 11.
https://wandbox.org/permlink/nUNiUwWWTr7a0NXM
Metode ini bekerja di C ++ 11 dan cukup umum. Dalam pengalaman saya, metode ini kuat, tetapi bukan yang paling performan.
sumber