替代 std::binary_function
replacement for std::binary_function
std::binary_function
is deprecated now and is going to be deleted in c++17. I searched on different publications, but I couldn't find a exact way to replace it. I'd like to know how should I write the following code in c++11风格。
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);
}
};
编辑
我按以下方式使用函数:
output[j] = *std::max_element(input.begin() + prev,
input.begin() + pos,
absoluteLess<float>());
input
和 output
是 std::vector
,在 for 循环中。
std::binary_function
唯一做的就是提供成员类型定义 result_type
、first_argument_type
和 second_argument_type
。标准库中唯一使用这些 typedef 的是 std::not2
,它 1) 被 C++17 std::not_fn
严格取代,2) 很容易被 lambda 替换,3) 在C++17,可能会在下一个修订版中删除。
如果出于某种原因,您需要使用 not2
,遗留绑定器(bind1st
/bind2nd
,均在 C++11 中弃用并在 C++ 中删除17), 或者遵循该协议的一些古老的第三方事物,替代方法是直接在 class:
中定义 typedef
using result_type = bool;
using first_argument_type = T;
using second_argument_type = T;
否则,只需删除继承即可。
首先,我的建议是观看CppCon 2015: Stephan T. Lavavej "functional: What's New, And Proper Usage"。 std::binary_function
在幻灯片 36 中提到,在视频中大约 36 分钟。您可以在 github.com/CppCon/CppCon2015) 找到这些幻灯片。它没有详细说明为什么你不应该使用 std::binary_function
,但如果你使用的是自 C++11 以来不推荐使用的东西,那么你可能会从观看它中受益。
如果您想了解不使用它的实际理由,请尝试 n4190:
unary_function/binary_function were useful helpers when C++98-era
adaptors needed argument_type/etc. typedefs. Such typedefs are
unnecessary given C++11's perfect forwarding, decltype, and so forth.
(And they're inapplicable to overloaded/templated function call
operators.) Even if a class wants to provide these typedefs for
backwards compatibility, it can do so directly (at a minor cost in
verbosity) instead of inheriting from unary_function/binary_function,
which is what the Standard itself started doing when these helpers
were deprecated.
现在您根本不需要它,因此您可以从您的程序中删除它的所有痕迹。
在 C++14 中,添加了透明比较器。但它可以在 C++11 中实现。专门针对 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));
}
}
};
现在可以推导出类型:
std::max_element(v.begin(), v.end(), absoluteLess<>());
我相信您正在寻找 std::function。
binary_function
可以很容易地替换为 lambda
函数:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
// Lambdas can be declared in the global scope
auto absolute = [](auto& x)->float{ return x<0?-x:x;};
int main()
{
// Lambdas can be declared embedded in functions
auto absoluteLess = [&](auto&x, auto&y)->bool{ return absolute(x)>absolute(y);};
auto absoluteGreater = [&](auto&x, auto&y)->bool{ return absolute(x)<absolute(y);};
std::vector<float> input={-2.0, 0.0, 3.4, -123.0};
std::cout << *std::max_element(input.begin(), input.end(), absoluteLess) <<std::endl;
std::cout << *std::max_element(input.begin(), input.end(), absoluteGreater) <<std::endl;
return 0;
}
std::binary_function
is deprecated now and is going to be deleted in c++17. I searched on different publications, but I couldn't find a exact way to replace it. I'd like to know how should I write the following code in c++11风格。
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);
}
};
编辑
我按以下方式使用函数:
output[j] = *std::max_element(input.begin() + prev,
input.begin() + pos,
absoluteLess<float>());
input
和 output
是 std::vector
,在 for 循环中。
std::binary_function
唯一做的就是提供成员类型定义 result_type
、first_argument_type
和 second_argument_type
。标准库中唯一使用这些 typedef 的是 std::not2
,它 1) 被 C++17 std::not_fn
严格取代,2) 很容易被 lambda 替换,3) 在C++17,可能会在下一个修订版中删除。
如果出于某种原因,您需要使用 not2
,遗留绑定器(bind1st
/bind2nd
,均在 C++11 中弃用并在 C++ 中删除17), 或者遵循该协议的一些古老的第三方事物,替代方法是直接在 class:
using result_type = bool;
using first_argument_type = T;
using second_argument_type = T;
否则,只需删除继承即可。
首先,我的建议是观看CppCon 2015: Stephan T. Lavavej "functional: What's New, And Proper Usage"。 std::binary_function
在幻灯片 36 中提到,在视频中大约 36 分钟。您可以在 github.com/CppCon/CppCon2015) 找到这些幻灯片。它没有详细说明为什么你不应该使用 std::binary_function
,但如果你使用的是自 C++11 以来不推荐使用的东西,那么你可能会从观看它中受益。
如果您想了解不使用它的实际理由,请尝试 n4190:
unary_function/binary_function were useful helpers when C++98-era adaptors needed argument_type/etc. typedefs. Such typedefs are unnecessary given C++11's perfect forwarding, decltype, and so forth. (And they're inapplicable to overloaded/templated function call operators.) Even if a class wants to provide these typedefs for backwards compatibility, it can do so directly (at a minor cost in verbosity) instead of inheriting from unary_function/binary_function, which is what the Standard itself started doing when these helpers were deprecated.
现在您根本不需要它,因此您可以从您的程序中删除它的所有痕迹。
在 C++14 中,添加了透明比较器。但它可以在 C++11 中实现。专门针对 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));
}
}
};
现在可以推导出类型:
std::max_element(v.begin(), v.end(), absoluteLess<>());
我相信您正在寻找 std::function。
binary_function
可以很容易地替换为 lambda
函数:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
// Lambdas can be declared in the global scope
auto absolute = [](auto& x)->float{ return x<0?-x:x;};
int main()
{
// Lambdas can be declared embedded in functions
auto absoluteLess = [&](auto&x, auto&y)->bool{ return absolute(x)>absolute(y);};
auto absoluteGreater = [&](auto&x, auto&y)->bool{ return absolute(x)<absolute(y);};
std::vector<float> input={-2.0, 0.0, 3.4, -123.0};
std::cout << *std::max_element(input.begin(), input.end(), absoluteLess) <<std::endl;
std::cout << *std::max_element(input.begin(), input.end(), absoluteGreater) <<std::endl;
return 0;
}