实现我自己的 myless
implement my own myless
我想了解 std::less 是如何实现的,所以我可以说
template <typename T>
struct myless
{
constexpr bool operator()(const T &lhs, const T &rhs) const
{
return lhs < rhs;
}
};
template <typename A, typename B, typename U = myless> // std::less works
bool f(A a, B b, U u = U())
{
return u(a, b);
}
int main()
{
std::cout << std::boolalpha;
std::cout << f("AB/CD", "CD/AB") << '\n';
std::cout << f(100, 10) << '\n';
}
这行不通。有什么建议吗?
您的 myless
模板采用单一类型,但您的 f
函数采用两种类型(即,它们可能是不同的类型)。支持这一点是可能的,但涉及更多。您是否打算改为执行以下操作?
template<typename T, typename U = myless<T>>
bool f(T a, T b, U u = U())
{
return u(a, b);
}
编辑
正如@vscoftco 指出的那样,支持不同的类型可能是预期的用例。如果要明确支持不同的类型,那么我会像这样实现它。
template<typename A, typename B, typename U = myless<typename std::common_type<A, B>::type>>
bool f(A a, B b, U u = U())
{
return u(a, b);
}
似乎此解决方案与 SFINAE 兼容 (C++17),http://en.cppreference.com/w/cpp/types/common_type。
If sizeof...(T) is zero or if there is no common type, the member type is not defined (std::common_type is SFINAE-friendly)
f("AB/CD", "CD/AB",)
(逗号)中有错别字。
它应该是 typename U = myless<A>
因为 myless
不在 std
命名空间中。
此外,参数可能应该通过引用传递:bool f(const A& a, const B& b, const U& u = U())
.
std::less
需要两个操作数是同一类型(逻辑上),并且 myless
也是这样定义的。因此,将 myless<A>
用于 U
会将 B
对象转换为 A
进行比较(通过使用其复制构造函数创建一个临时对象)。
自 C++14 起,还有操作数可以具有不同类型的特化 std::less<void>
,以及非 bool 的 return 类型。它将一对一映射到 operator<
的作用。参见 http://en.cppreference.com/w/cpp/utility/functional/less_void。
代码的更正版本:
#include <iostream>
template <typename T>
struct myless
{
constexpr bool operator()(const T &lhs, const T &rhs) const
{
return lhs < rhs;
}
};
template <typename A, typename B, typename U = myless<A>>
bool f(const A& a, const B& b, const U& u = U())
{
return u(a, b);
}
int main()
{
std::cout << std::boolalpha;
std::cout << f("AB/CD", "CD/AB") << '\n';
std::cout << f(100, 10) << '\n';
}
对于可以有不同类型和非布尔类型的版本 return 类型:
struct myless2 {
template<class T, class U>
constexpr auto operator()(const T& t, const U& u) const -> decltype(t < u) {
return t < u;
}
};
std::less<void>
似乎也支持 r 值引用,因为当 operator<
是这样定义的(当时可能做的不是比较。)
我想了解 std::less 是如何实现的,所以我可以说
template <typename T>
struct myless
{
constexpr bool operator()(const T &lhs, const T &rhs) const
{
return lhs < rhs;
}
};
template <typename A, typename B, typename U = myless> // std::less works
bool f(A a, B b, U u = U())
{
return u(a, b);
}
int main()
{
std::cout << std::boolalpha;
std::cout << f("AB/CD", "CD/AB") << '\n';
std::cout << f(100, 10) << '\n';
}
这行不通。有什么建议吗?
您的 myless
模板采用单一类型,但您的 f
函数采用两种类型(即,它们可能是不同的类型)。支持这一点是可能的,但涉及更多。您是否打算改为执行以下操作?
template<typename T, typename U = myless<T>>
bool f(T a, T b, U u = U())
{
return u(a, b);
}
编辑
正如@vscoftco 指出的那样,支持不同的类型可能是预期的用例。如果要明确支持不同的类型,那么我会像这样实现它。
template<typename A, typename B, typename U = myless<typename std::common_type<A, B>::type>>
bool f(A a, B b, U u = U())
{
return u(a, b);
}
似乎此解决方案与 SFINAE 兼容 (C++17),http://en.cppreference.com/w/cpp/types/common_type。
If sizeof...(T) is zero or if there is no common type, the member type is not defined (std::common_type is SFINAE-friendly)
f("AB/CD", "CD/AB",)
(逗号)中有错别字。
它应该是 typename U = myless<A>
因为 myless
不在 std
命名空间中。
此外,参数可能应该通过引用传递:bool f(const A& a, const B& b, const U& u = U())
.
std::less
需要两个操作数是同一类型(逻辑上),并且 myless
也是这样定义的。因此,将 myless<A>
用于 U
会将 B
对象转换为 A
进行比较(通过使用其复制构造函数创建一个临时对象)。
自 C++14 起,还有操作数可以具有不同类型的特化 std::less<void>
,以及非 bool 的 return 类型。它将一对一映射到 operator<
的作用。参见 http://en.cppreference.com/w/cpp/utility/functional/less_void。
代码的更正版本:
#include <iostream>
template <typename T>
struct myless
{
constexpr bool operator()(const T &lhs, const T &rhs) const
{
return lhs < rhs;
}
};
template <typename A, typename B, typename U = myless<A>>
bool f(const A& a, const B& b, const U& u = U())
{
return u(a, b);
}
int main()
{
std::cout << std::boolalpha;
std::cout << f("AB/CD", "CD/AB") << '\n';
std::cout << f(100, 10) << '\n';
}
对于可以有不同类型和非布尔类型的版本 return 类型:
struct myless2 {
template<class T, class U>
constexpr auto operator()(const T& t, const U& u) const -> decltype(t < u) {
return t < u;
}
};
std::less<void>
似乎也支持 r 值引用,因为当 operator<
是这样定义的(当时可能做的不是比较。)