Mengapa tidak berhasil
Saya mengharapkan kompiler untuk menyelesaikan f()dengan tipe iterator. Rupanya, itu (gcc 4.1.2) tidak melakukannya.
Akan lebih bagus jika itu masalahnya! Namun, for_eachadalah template fungsi, dideklarasikan sebagai:
template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator, InputIterator, UnaryFunction );
Pemotongan template perlu memilih jenis untuk UnaryFunctionpada saat panggilan. Tetapi ftidak memiliki tipe tertentu - ini adalah fungsi yang kelebihan beban, ada banyak fyang masing-masing memiliki tipe yang berbeda. Saat ini tidak ada cara untuk for_eachmembantu proses pemotongan template dengan menyatakan yang fdiinginkan, jadi pemotongan template gagal. Agar pemotongan template berhasil, Anda perlu melakukan lebih banyak pekerjaan di situs panggilan.
Solusi umum untuk memperbaikinya
Melompat ke sini beberapa tahun dan C ++ 14 kemudian. Daripada menggunakan a static_cast(yang akan memungkinkan pemotongan template berhasil dengan "memperbaiki" yang fingin kita gunakan, tetapi mengharuskan Anda untuk melakukan resolusi berlebih secara manual untuk "memperbaiki" yang benar), kami ingin membuat kompilator berfungsi untuk kita. Kami ingin fmengajukan beberapa argumen. Dengan cara yang paling umum, itu:
[&](auto&&... args) -> decltype(auto) { return f(std::forward<decltype(args)>(args)...); }
Itu banyak untuk diketik, tapi masalah semacam ini sering muncul menjengkelkan, jadi kita bisa membungkusnya dalam makro (menghela napas):
#define AS_LAMBDA(func) [&](auto&&... args) -> decltype(func(std::forward<decltype(args)>(args)...)) { return func(std::forward<decltype(args)>(args)...); }
dan kemudian gunakan saja:
void scan(const std::string& s) {
std::for_each(s.begin(), s.end(), AS_LAMBDA(f));
}
Ini akan melakukan apa yang Anda inginkan dari kompilator - melakukan resolusi overload pada namanya fdan melakukan hal yang benar. Ini akan berfungsi terlepas dari apakah ffungsi bebas atau fungsi anggota.