2015-10-14 15 views
11

binary_function không còn được dùng nữa và sẽ bị xóa trong C++ 17. Tôi đã tìm kiếm trên các ấn phẩm khác nhau, nhưng tôi không thể tìm thấy một cách chính xác để thay thế nó. Tôi muốn biết làm thế nào tôi nên viết đoạn mã sau trong C + + 11 phong cách.thay thế cho binary_function

template <class T> 
inline T absolute(const T &x) { 
    return (x >= 0) ? x : -x; 
} 

template <class T> 
struct absoluteLess : public std::binary_function<T, T, bool> { 
    bool operator()(const T &x, const T &y) const { 
     return absolute(x) < absolute(y); 
    } 
}; 

template <class T> 
struct absoluteGreater : public std::binary_function<T, T, bool> { 
    bool operator()(T &x, T &y) const { 
     return absolute(x) > absolute(y); 
    } 
}; 

EDIT: Tôi đang sử dụng các chức năng theo cách sau:

output[j] = *std::max_element(input.begin() + prev, input.begin() + pos, absoluteLess<float>()); 

đầu vào và đầu ra là vectơ, bên trong một vòng lặp for

+2

lý do tại sao bạn cần nó?loại đặc điểm và decltype có thể tìm ra loại 'toán tử()' mà không có nhu cầu của 'binary_function' –

+2

Làm thế nào để bạn sử dụng các hàm mẫu này? Câu trả lời phụ thuộc vào cách sử dụng. – Rostislav

+1

http://stackoverflow.com/a/22863957/642626 thats cách bạn tìm ra các đối số và kiểu trả về của bất kỳ đối tượng có thể gọi nào. –

Trả lời

7

Trước tiên, lời khuyên của tôi là xem CppCon 2015: Stephan T. Lavavej "functional: What's New, And Proper Usage". std::binary_function được đề cập trên trang trình bày 36, khoảng 36 phút trong video. Bạn có thể tìm thấy các trang trình bày tại github.com/CppCon/CppCon2015). Nó không đi vào chi tiết lý do tại sao bạn không nên sử dụng std::binary_function, nhưng nếu bạn đang sử dụng một cái gì đó không được dùng nữa kể từ C++ 11, thì có thể bạn sẽ được lợi từ việc xem nó.

Nếu bạn muốn các lý do thực tế không sử dụng nó, hãy thử n4190:

unary_function/binary_function là những người giúp đỡ hữu ích khi C++ 98-kỷ nguyên adapter cần argument_type/etc. typedefs. Các typedefs như vậy là không cần thiết cho việc chuyển tiếp hoàn hảo của C++ 11, decltype, v.v. (Và chúng không thể áp dụng cho các hàm quá tải/templated gọi là các toán tử .) Ngay cả khi một lớp muốn cung cấp các kiểu gõ này cho khả năng tương thích ngược, nó có thể thực hiện trực tiếp (với chi phí nhỏ là độ dài) thay vì kế thừa từ unary_function/binary_function, đó là những gì bản thân tiêu chuẩn bắt đầu thực hiện khi những người giúp đỡ này không được chấp nhận.

Bây giờ bạn chỉ đơn giản là không cần nó, vì vậy bạn có thể loại bỏ tất cả dấu vết của nó khỏi chương trình của bạn.

Trong C++ 14, các trình so sánh trong suốt đã được thêm vào. Nhưng nó có thể được thực hiện trong C++ 11. Chỉ cần chuyên nó cho void:

template<> 
struct absoluteLess<void> { 
    template< class T, class U> 
    constexpr auto operator()(T&& lhs, U&& rhs) const 
     -> decltype(absolute(std::forward<T>(lhs)) < absolute(std::forward<U>(rhs))) 
    { 
     return absolute(std::forward<T>(lhs)) < absolute(std::forward<U>(rhs)); 
    } 
} 
}; 

Bây giờ loại có thể suy ra:

std::max_element(v.begin(), v.end(), absoluteLess<>()); 
+0

Nó hoạt động tốt! Liên kết cũng rất hữu ích. – Luis

8

Điều duy nhất std::binary_function không được cung cấp thành viên typedefs result_type, first_argument_typesecond_argument_type. Và điều duy nhất trong thư viện chuẩn sử dụng các typedef này là std::not2, là 1) được thay thế hoàn toàn bởi C++ 17 std::not_fn, 2) dễ dàng thay thế bằng lambda, và 3) không được dùng trong C++ 17 và có khả năng sẽ được xóa trong bản sửa đổi tiếp theo.

Nếu vì bất cứ lý do nào, bạn cần phải sử dụng not2, các chất kết dính di sản (bind1st/bind2nd, cả hai bị phản đối trong C++ 11 và loại bỏ trong C++ 17), hoặc một số điều của bên thứ ba cổ sau giao thức , thay thế là xác định typedef trực tiếp trong lớp học của bạn:

Nếu không, chỉ cần loại bỏ thừa kế.