2015-10-14 14 views
11

binary_function ist jetzt veraltet und wird in C++ 17 gelöscht werden. Ich habe nach verschiedenen Veröffentlichungen gesucht, aber ich konnte keine genaue Methode finden, sie zu ersetzen. Ich würde gerne wissen, wie ich den folgenden Code in C++ 11-Stil schreiben soll.Ersatz für 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: I die Funktionen in der folgenden Weise bin mit:

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

Eingangs- und Ausgangsvektoren sind, im Inneren einer for-Schleife

+2

warum Sie es brauchen?type traits und declltype können den Typ von 'operator()' ohne die Anforderungen von 'binary_function' ermitteln –

+2

Wie benutzt man diese Template-Funktionen? Die Antwort hängt von der Verwendung ab. – Rostislav

+1

http://stackoverflow.com/a/22863957/642626 das ist, wie Sie die Argumente und den Rückgabetyp jedes aufrufbaren Objekts herausfinden. –

Antwort

7

Zuerst ist mein Rat zu sehen CppCon 2015: Stephan T. Lavavej "functional: What's New, And Proper Usage". std::binary_function wird auf Folie 36 erwähnt, etwa 36 Minuten im Video. Sie finden die Folien unter github.com/CppCon/CppCon2015). Es geht nicht ins Detail, warum Sie nicht std::binary_function verwenden sollten, aber wenn Sie etwas verwenden, das seit C++ 11 veraltet ist, dann würden Sie wahrscheinlich davon profitieren, es anzuschauen.

Wenn Sie die tatsächlichen Gründe wollen für ihn nicht benutzen, versuchen n4190:

unary_function/binary_function waren nützliche Helfer, wenn C++ 98-Ära Adapter benötigten argument_type/etc. typedefs. Solche typedefs sind unnötig gegeben C++ 11 die perfekte Weiterleitung, decltype und so weiter. (Und sie sind nicht anwendbar auf überladene/templated Funktionsaufruf Operatoren.) Auch wenn eine Klasse diese Typdefs für Abwärtskompatibilität bieten will, kann es direkt (zu geringen Kosten in Ausführlichkeit) anstelle von unary_function erben/binary_function, , was der Standard selbst zu tun begann, als diese Helfer veraltet waren.

Jetzt brauchen Sie es einfach nicht mehr, damit Sie alle Spuren davon aus Ihrem Programm entfernen können.

In C++ 14 wurden transparente Komparatoren hinzugefügt. Aber es kann in C++ 11 implementiert werden. spezialisieren Sie es einfach für 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)); 
    } 
} 
}; 

Nun kann der Typ ableiten:

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

Es funktioniert gut! Die Verbindung ist auch sehr nützlich. – Luis

8

Das einzige, was std::binary_function tut, ist die Bereitstellung von member typedefs , first_argument_type und second_argument_type. Und das einzige Ding in der Standardbibliothek, die diese typedefs benutzt, ist std::not2, das 1) durch C++ 17 std::not_fn, das 2) leicht durch ein Lambda sowieso ersetzt wird, und 3) veraltet in C++ 17 und wahrscheinlich gehen wird in der nächsten Revision entfernt werden.

Wenn aus welchem ​​Grund auch immer, müssen Sie not2 verwenden, die Legacy-Bindemittel (bind1st/bind2nd sowohl veraltet in C++ 11 und entfernt in C++ 17), oder einige alte Dritter Sache folgende dieses Protokoll , die Ersetzung ist, die typedefs direkt in Ihrer Klasse zu definieren:

using result_type = bool; 
using first_argument_type = T; 
using second_argument_type = T; 

Andernfalls entfernen Sie einfach die Vererbung.