Tại sao nó không hoạt động
Tôi mong muốn trình biên dịch giải quyết f()theo kiểu lặp. Rõ ràng, nó (gcc 4.1.2) không làm điều đó.
Sẽ thật tuyệt nếu đó là trường hợp! Tuy nhiên, for_eachlà một mẫu hàm, được khai báo là:
template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator, InputIterator, UnaryFunction );
Khấu trừ mẫu cần chọn một loại cho UnaryFunctionđiểm tại của cuộc gọi. Nhưng fkhông có một loại cụ thể - đó là một hàm quá tải, có nhiều floại với mỗi loại khác nhau. Không có cách nào hiện tại for_eachđể hỗ trợ quá trình khấu trừ mẫu bằng cách nêu rõ fnó muốn, vì vậy việc khấu trừ mẫu đơn giản là thất bại. Để việc khấu trừ mẫu thành công, bạn cần thực hiện nhiều công việc hơn trên trang web cuộc gọi.
Giải pháp chung để sửa nó
Nhảy vào đây một vài năm và C ++ 14 sau đó. Thay vì sử dụng static_cast(sẽ cho phép khấu trừ mẫu thành công bằng cách "sửa" mà fchúng tôi muốn sử dụng, nhưng yêu cầu bạn phải tự giải quyết quá tải để "sửa" chính xác), chúng tôi muốn làm cho trình biên dịch hoạt động cho chúng tôi. Chúng tôi muốn gọi fvề một số đối số. Theo cách chung nhất có thể, đó là:
[&](auto&&... args) -> decltype(auto) { return f(std::forward<decltype(args)>(args)...); }
Đó là rất nhiều loại, nhưng loại vấn đề này xuất hiện thường xuyên một cách khó chịu, vì vậy chúng ta chỉ có thể gói nó trong một macro (thở dài):
#define AS_LAMBDA(func) [&](auto&&... args) -> decltype(func(std::forward<decltype(args)>(args)...)) { return func(std::forward<decltype(args)>(args)...); }
và sau đó chỉ cần sử dụng nó:
void scan(const std::string& s) {
std::for_each(s.begin(), s.end(), AS_LAMBDA(f));
}
Điều này sẽ làm chính xác những gì bạn muốn trình biên dịch đã làm - thực hiện giải quyết quá tải trên fchính tên đó và chỉ cần làm đúng. Điều này sẽ hoạt động bất kể flà chức năng miễn phí hay chức năng thành viên.