2017-02-23 107 views
1

需要異步運行一個函數,當函數採用模板參數。下面的代碼不能編譯,有幫助嗎?呼叫模板功能與異步

template<typename T> 
void say(int n, T t) { 
    cout << " say: " << n << " " << t << endl; 
} 

template<typename F, typename... Ts> 
inline auto reallyAsync(F&& f, Ts&&... params){ 
    return std::async(
     std::launch::async, 
     std::forward<F>(f), 
     std::forward<Ts>(params)...); 
} 

int main() { 
    int n = 10; float x = 100; 
    say(n, x); // works 
    reallyAsync(&say, n, x) ; // does not work 
} 
+1

這將有助於增加編譯器會引發出用於 – Stormenet

+0

@Stormenet或編譯器錯誤。 –

回答

1

say函數模板,你不能把一個函數模板的地址,因爲它沒有一個功能(見註釋):

int main() { 
    int n = 10; float x = 100; 
    say(n, x);    // works because of template argument deduction 
    reallyAsync(&say, n, x); //fails because say isn't a resolved function. 
} 

但是,您可以通的一個實例說

int main() { 
    int n = 10; float x = 100; 
    say(n, x);      // works 
    reallyAsync(&say<decltype(x)>, n, x); 
} 

輸出:

say: 10 100 
say: 10 100 

Live Example

1

基本上,say不是一個函數,它是一個函數模板。您無法獲得&模板的地址。

只是改變:

reallyAsync(&say, n, x) 

到:

reallyAsync(&say<float>, n, x) 

,它應該工作。

1
reallyAsync(&say, n, x) 

say是一個模板。在C++中,您無法獲取模板的地址。這是一個毫無意義的主張。

理解模板和模板實例之間的區別很重要。模板只不過是一種規格說明。它不存在任何實際或有意義的術語。而且操作符的地址只能用真實的,實際的對象,以某種方式存在於某處。

要消除編譯錯誤,你必須實例化模板,把它變成實實在在的東西:從您的角度來看

reallyAsync(&say<float>, n, x); 

這可能不是理想的,並且擊敗的目的模板功能。可能有更好的,不同的方式來做你真正想做的事情,而不需要明確的模板實例化。