在C++中如何将一个模板化的函数作为另一个函数的参数,并提供一个默认值?

问题描述 投票:0回答:1

如何让一个模板化的函数作为另一个函数的参数,并提供一个默认值?

例如,如果我想为一个函数提供一个模板化的排序函数,但它的默认值是std::sort,那会是什么样的呢?

下面的例子不能用。

#include <algorithm> // std::sort

template <class iterator_type, class sort_comparison>
void temp(void (*sort_func)(iterator_type, iterator_type, sort_comparison) = std::sort)
{
    return;
}



int main()
{
    temp();

    return 0;
}

根据gcc的错误信息,它仍然需要提供一个参数。

c++ function templates parameters default
1个回答
3
投票

另一种较少约束的解决方案是将一个函数的默认值包装成 std::sort 或其他函数模板调用到lambda对象中。

template <class Container, class Sort>
void temp(Container& c, Sort sort) {
    sort(c);
}

template <class Container>
void temp(Container& c) {
    temp(c, [](auto& c) { std::sort(c.begin(), c.end()); });
}

int main() {
    std::vector<int> v;
    temp(v);
    temp(v, [](auto& c) { std::stable_sort(c.begin(), c.end()); });

    std::list<int> l;
    temp(l, [](auto& c) { c.sort(); }); // std::sort is incompatible with std::list
}

在C++03中,lambda表达式是不可用的(有有限的替代品,如 boost::lambda 但它有完全相同的限制,那就是它需要一个函数指针,不能调用函数模板,不像C++11的lambda),这样你就必须显式地编写那个函数类的代码(但它给你提供了更灵活的重载)。

struct Sort {
    template<class C>
    void operator()(C& c) {
        std::sort(c.begin(), c.end());
    }

    template<class T, class A>
    void operator()(std::list<T, A>& c) {
        c.sort();
    }
};
// ...
    temp(v, Sort());
    temp(l, Sort());

不过,这可能是C++03中最简单,最快的编译和执行方案。虽然它很啰嗦,而且是非局部的,但这是在C++03中能做到的最简单的方案。

© www.soinside.com 2019 - 2024. All rights reserved.