2013-06-02 178 views
1

我试图编译如下:与模板函数作为参数可变参数模板功能

#include <vector> 
#include <array> 

template <typename T> 
void sort(T &container) {} 

template <typename F, typename T, typename ...Tail> 
void sort_containers(F sort_func, T &container, Tail &...tail) { 
    sort_func(container); 
    sort_containers(sort_func, tail...); 
} 

template <typename F, typename T> 
void sort_containers(F sort_func, T &container) { 
    sort_func(container); 
} 

int main() { 
    std::vector<int> x = {1,2,3}; 
    std::vector<double> y = {1.0, 2.0, 3.0}; 
    std::array<char, 3> z = {{'d' , 'b', 'c'}}; 
    sort_containers(sort, x, y, z); 
} 

导致以下编译器错误与G ++ 4.8:

error: no matching function for call to 
‘sort_containers(<unresolved overloaded function type>, 
std::vector<int>&, std::vector<double>&, std::array<char, 3u>&)’ 

我了解我需要在将sort传递给sort_containers时指定模板参数,但我不确定这是如何在存在可变模板函数的情况下工作的。

+0

它的工作原理与使用非变化模板'sort_three_containers'一样。也就是说,不太好。您不需要传递函数(模板),而是使用具有成员函数模板的对象进行排序,以便每次递归调用sort_containers时都会发生实例化。 –

+0

使用非variadic模板,我可以执行以下操作:http://ideone.com/jBg5yT,但我想这个例子不会扩展到'sort_three_containers' – countfromzero

回答

4

template功能是功能工厂,而不是功能。他们不能直接传递。

现在,函子可以是,和相对简单的包装可以打开的功能的过载设定成算符:

struct sort_functor { 
    template<typename...Args> 
    auto operator()(Args&&... args) const -> 
    decltype(sort(std::forward<Args>(args)...)) 
    { return sort(std::forward<Args>(args)...); } 
}; 

其可以经由宏来产生,而不是由template,因为你无法通过超载设置!您然后通过sort_functor()到您的其他template

#define MAKE_OVERLOAD_FUNCTOR(NAME) \ 
    struct CONCAT(NAME, _functor) { \ 
    template<typename...Args> \ 
    auto operator()(Args&&... args) const -> \ 
    decltype(NAME(std::forward<Args>(args)...)) \ 
    { return NAME(std::forward<Args>(args)...) } \ 
    }; 

有使经由[]令牌进一步滥用产生上述仿函数自动地提案。

+1

Pff,“滥用”。我只是依赖lambda语法。 :P – Xeo

+0

我说“*进一步*滥用”:) Lambda语法是最初的滥用@xeo – Yakk