c++ - 函数模板语法的默认模板参数

标签 c++ templates

有什么区别

template <typename ForwardIter, 
    typename Comp = std::less<typename std::iterator_traits<ForwardIter>::value_type>>
void select_sort(ForwardIter first, ForwardIter last, Comp comp = Comp())
{
    for (; first != last; ++first)
    {
        auto iter = std::min_element(first, last, comp);
        std::swap(*first, *iter);
    }
}

和更简单的版本

template <typename ForwardIter, 
    typename Comp = std::less<>>
void select_sort(ForwardIter first, ForwardIter last, Comp comp = Comp())
{
    // Same as above
}

两者似乎都有效。这只是风格问题吗?还是必须二选一的情况?

最佳答案

两者都可以,但它们是不同的。

std::less<T>是最常见的用例。这是一个具有 operator() 的类重载。它的实现方式与此类似。

我在这里省略了一些关于指针的特殊情况,但为了简单起见,这只是一个简单的实现。

template<typename T>
struct less {
    constexpr bool operator()(const T &lhs, const T &rhs) const {
        return lhs < rhs;
    }
};

它就像一个仿函数,但你选择哪个 T这将是。这种解决方案的优点是可以专门化 std::less<T>对于代码的特殊情况。

std::less<>是不同的。它可以比较任何类型的对象,只要这两种类型有operator<。重载。它就像一个通用的 lambda。它的实现有点像这样:

template<>
struct less<void> {
    template<typename T, typename U>
    constexpr auto operator()(T&& lhs, U&& rhs) const
            -> decltype(std::declval<T>() < std::declval<U>()) {
        return std::forward<T>(lhs) < std::forward<U>(rhs);
    }
};

如您所见,当您使用 std::less<>{}(a, b) 时, 它真的和你写的一样 a < b , 甚至可以使用具有非常量 operator< 的类型.所以这个是最好的,只要你使用的类有 operator<重载。

关于c++ - 函数模板语法的默认模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41526484/

相关文章:

reactjs - WebStorm 功能片段 React

c++ - 关于自定义分配器和 STL 的模板声明、别名和特化说明

c++ - ARM NEON 转置 4x4 uint32

c++ - Qt/C 如何读取当前在帧缓冲区中的图像?

c++ - 在运行时设置 CMenu 项提示

c++ - C++11 模板中的默认位置参数

c++ - 使用可变参数模板的平方和

c++ - 编译多源文件时 Unresolved external 问题

c++ - Visual C++ .NET 中的多重继承

C++模板检查值