实现我自己的 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< 是这样定义的(当时可能做的不是比较。)