2016-11-02 85 views
3

我有一個TaskWrapper:作爲模板參數

template <typename T, T (*F)(T)> 
struct TaskWrapper { 
    static inline T run(T clock) { 
    return F(clock); 
    } 
}; 

使用它,我必須指定T模板參數:

uint16_t task1(uint16_t clock) { return clock + 1; } 
typedef tasks::TaskWrapper<uint16_t, task1> Task; 

我想簡單地寫:

typedef tasks::TaskWrapper<task1> Task; 

並讓編譯器確定返回和參數類型是uint16_t。

注:

的TaskWrapper明顯簡化,在現實中還有其它幾個參數,這些參數typedef的過程中傳遞。

包裹的功能只能是:

uint8_t task(uint8_t clock); 
uint16_t task(uint16_t clock); // or 
uint32_t task(uint32_t clock); 

的TaskWrapper作爲模板參數到另一個類,通過它會在某個時候調用任務::運行(...);

C++ 11會很好。

+1

什麼'模板使用任務=任務:: TaskWrapper ;'然後把它作爲任務''。 – Zereges

回答

3

只因爲C++ 17的template <auto>功能:

template <auto F> 
struct TaskWrapper { 
    template <typename T> 
    static inline auto run(T clock) { 
    return F(clock); 
    } 
}; 

uint16_t task1(uint16_t clock) { return clock + 1; } 
typedef TaskWrapper<&task1> Task; // ok 
+0

哦,我喜歡!在[我寫的這段代碼]中會非常有用(http://stackoverflow.com/a/40389000/103167) –

2

您可以將模板參數移動到調用的網站,但是這將使其對應被傳爲扣除的說法,如:

template <typename F, F functor> 
struct TaskWrapper { 
    template<typename T> 
    static inline T run(T clock) { 
    return functor(clock); 
    } 
}; 

uint16_t task1(uint16_t clock) { return clock + 1; } 
typedef TaskWrapper<decltype(task1), task1> Task; 

int main(int argc, const char * argv[]) 
{ 
    Task task; 
    Task::run(10); 
    return 0; 
} 

因此,它會生成一個static inline int run(int clock),這是不初始函數的相同參數類型,但可能足以滿足您的需求。

1

我不認爲這是可能的你到底在問什麼:如果你想通過函數作爲模板的值,沒有表達類型,你必須知道之前的類型;但函數的類型是你想要推斷的。

如果接受傳遞類型的功能,如下

template <typename> 
struct taskWrapper; 

template <typename T> 
struct taskWrapper<std::function<T(T)>> 
{ 
    static inline T run (std::function<T(T)> const & F, T clock) 
    { return F(clock); }; 
}; 

可以定義定義typedef小號

typedef taskWrapper<std::function<decltype(task8)>> tsk8; 
typedef taskWrapper<std::function<decltype(task16)>> tsk16; 
typedef taskWrapper<std::function<decltype(task32)>> tsk32; 

,但你可以看到,taskWrapper<std::function<decltype(task8)>>只知道類型task8(),而不是task8()函數本身;所以你必須將該功能傳遞給run()

以下是一個工作示例。

#include <iostream> 
#include <functional> 

template <typename> 
struct taskWrapper; 

template <typename T> 
struct taskWrapper<std::function<T(T)>> 
{ 
    static inline T run (std::function<T(T)> const & F, T clock) 
    { return F(clock); }; 
}; 

uint8_t task8 (uint8_t clock) 
{ return ++clock; } 

uint16_t task16 (uint16_t clock) 
{ return ++clock; } 

uint32_t task32 (uint32_t clock) 
{ return ++clock; } 

typedef taskWrapper<std::function<decltype(task8)>> tsk8; 
typedef taskWrapper<std::function<decltype(task16)>> tsk16; 
typedef taskWrapper<std::function<decltype(task32)>> tsk32; 

int main() 
{ 
    tsk8 t8; 
    tsk16 t16; 
    tsk32 t32; 

    std::cout << t8.run(task8, uint8_t(64)) << std::endl; // print A 
    std::cout << t16.run(task16, uint16_t(65)) << std::endl; // print 66 
    std::cout << t32.run(task32, uint32_t(66)) << std::endl; // print 67 
} 

希望這會有所幫助。

2

使用的模板類型時,不作爲參數值是容易的。你能將你的函數轉換爲函子嗎?如果是的話,那麼一個可能的解決方案是:

template<class F> 
struct TaskWrapper { 
    using T = decltype(F::operator()); 
    static inline T run(T clock) { 
    return F(clock); 
    } 
}; 

struct task1_t { 
    uint16_t operator()(uint16_t clock) { 
    return clock + 1; 
    } 
}; 

using Task = TaskWrapper<task1_t>;