2014-10-15 15 views
7

Lý do chính cho con trỏ hàm là cung cấp các đối tượng có thể gọi chung, nhưng trong C++ 11 cách để cung cấp nó là sử dụng std::function, vì vậy có bất kỳ lý do nào để sử dụng con trỏ hàm trong C++ hiện đại từ khả năng tương thích với C? Nói cách khác, là std::function phiên bản hiện đại của các con trỏ hàm, chính xác như std::array và các mảng được tích hợp sẵn?sử dụng con trỏ hàm trong C++ 11

+1

lý do tại sao bạn gọi các đối tượng có thể gọi là các đối tượng chung có thể gọi được? – Jamboree

+0

Tôi có nghĩa là bạn có thể gán các chức năng khác nhau có cùng chữ ký cho một con trỏ hàm –

+1

Có thể có các cân nhắc về hiệu quả. 'std :: functions' có thêm indirections và không phải là miễn phí. – juanchopanza

Trả lời

3

Có Tôi thích std::function gần như ở khắp mọi nơi nhưng có rất ít trường hợp mà kích thước trên không và hướng dẫn của std::function có thể không được chấp nhận. Đối với các cuộc gọi nhỏ như con trỏ chức năng được bao bọc trong std::function, thường không có thêm hướng dẫn và không có phân bổ bộ nhớ động kể từ khi có thể gọi được vào số std::function nhưng std::function có thể lớn để giữ các cuộc gọi lớn hơn để có thể có phí trên không lớn.

+0

Khi nào bạn sử dụng 'std :: function' thay vì chỉ các biểu thức lambda? Khi bạn muốn có thể cung cấp các loại triển khai khác và bạn không muốn làm điều đó bằng cách gói chúng trong lambdas? – Jerry101

+0

@ Jerry101 Có giống như con trỏ hàm tôi sử dụng chúng để chuyển đổi giữa các triển khai khác nhau hoặc để cho người gọi cung cấp một số loại chức năng như gọi lại. Bạn không thể làm điều này với lambdas vì mỗi lambda có kiểu riêng của nó. – TNA

+1

Mục đích chính của std :: function là loại tẩy xoá và thích ứng. Con trỏ chức năng có loại nghiêm ngặt. std :: function là một hàm bao hàm đa hình, nó có thể liên kết với một hàm tự do, một hàm tĩnh lớp, một hàm thành viên, và nó có thể được sử dụng cho ứng dụng hàm một phần, v.v. Nếu bạn không cần tất cả, có lẽ không phải là công cụ thích hợp cho công việc, loại tẩy xóa không đến miễn phí, thường liên quan đến các cuộc gọi ảo và phân bổ đống (mặc dù thường có một tối ưu hóa bộ đệm nhỏ). – BenPope

2

Thành thật mà nói, tôi không thể nghĩ ra một trường hợp mà tôi cần std :: function, và đây là lý do tại sao. Nếu tôi bouncing con trỏ chức năng xung quanh ở tất cả, sau đó tôi có thể làm việc ở một mức độ rất thấp. Có lẽ lý do là sự thừa kế kiểu C++ đã chứng minh quá hạn chế nên tôi đang thiết kế tính đa hình của riêng mình. Ngoài ra, tôi có thể đang làm việc trên một bộ điều khiển nhúng nhỏ, nơi tôi thực sự cạo bỏ các byte. Dù bằng cách nào, tôi sẽ dựa vào bản thân mình, chứ không phải trên trình biên dịch, để nhớ những loại tôi đã có vv. Về cơ bản tôi muốn đập kim loại và muốn kim loại cư xử như kim loại, không giống như thang máy từ Sirius Cybernetics .

Trường hợp duy nhất mà tôi có khả năng muốn chi phí của hàm std :: là nếu tôi đang cố gắng thực hiện chức năng nào đó, chẳng hạn như đóng cửa, nhưng nếu tôi muốn thì tôi không thể sử dụng C++ ở tất cả.

+0

Java Script là gì, nhưng đóng cửa và con trỏ chức năng. Tôi sẽ không gọi đó là phong cách lập trình "mức thấp". :) Các yếu tố của lập trình chức năng có khả năng hữu ích bất kể mức độ thấp mà bạn tìm thấy chính mình. – Eugene

+0

* mọi thứ * từ xa tương tự như một hệ thống dựa trên sự kiện có lẽ sẽ tốt hơn nhiều với 'std :: function' hơn là các con trỏ hàm đơn giản. Việc truyền tham số 'void *' và thường không được ưa thích: P – CoffeeandCode

1

Trên hệ thống POSIX, bạn nhận được dlopen & dlsym và bạn sẽ sử dụng chúng để nhận các con trỏ hàm từ các plugin được nạp động.

Đây là một trường hợp sử dụng phổ biến nơi con trỏ chức năng vẫn còn hữu ích, ngay cả với C++ 14 (xem ví dụ Qt)

Và càng nhiều người quan sát, việc thực hiện đóng cửa (hoặc của std::function) thường sẽ yêu cầu thêm chi phí và thời gian chạy thêm.

1

std::function rất tiện dụng và hiệu quả đối với hầu hết các trường hợp sử dụng. Nhưng có một tính năng thiếu: bình đẳng. Vì vậy, mỗi lần bạn cần so sánh/lọc/tìm kiếm/sắp xếp std::function như các đối tượng, bạn phải quay trở lại các con trỏ hàm để thực hiện những gì bạn cần. Quay lại đầu trang |

+0

Tính bình đẳng của các hàm là không thể xác định được, nếu bạn quan tâm đến hành vi quan sát của chúng chỉ –

+0

Chắc chắn, đó là lý do tại sao các đối tượng 'std :: function' không thể so sánh được) – Stas

Các vấn đề liên quan