实施我自己的无能为力

时间:2015-03-11 22:54:44

标签: c++ c++11 c++14

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

这不起作用。有什么建议吗?

2 个答案:

答案 0 :(得分:3)

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。它将一对一映射到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';
}

对于可以具有不同类型的版本,以及非bool返回类型:

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<的定义是这样的(当时可能做比其他事情更多的事情。)

答案 1 :(得分:2)

您的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

  

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

相关问题