实现我自己的无我

implement my own myless

本文关键字:自己的 我自己 实现      更新时间:2023-10-16

我试图理解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';
}

这行不通。有什么建议吗?

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> for U 将使它将B对象转换为用于比较的A对象(通过使用其复制构造函数创建临时对象)。

自 C++14 以来,还有专门的std::less<void>,其中操作数可以具有不同的类型,以及不是布尔值的返回类型。它将一对一映射到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';
}

对于可以具有不同类型和非布尔返回类型的版本:

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<像这样定义时(然后可能会做比较以外的其他事情)。

您的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);
}

http://en.cppreference.com/w/cpp/types/common_type,该解决方案似乎也与SFINAE兼容(C++17)。

如果大小...(T) 为零,或者如果没有通用类型,则不定义成员类型(std::common_type 对 SFINAE 友好)