2013-06-02 173 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