2017-02-28 113 views
8

我只是偶然發現了一個小問題,這個問題在處理模板時給我帶來了困擾。這裏有一個例子:模板函數指針作爲模板參數

template<class _returnType, _returnType (*_function)()> 
_returnType aliasGetter() { return _function(); } 
int getCoolNumber() { return 42; } 
int main() 
{ 
    std::cout << aliasGetter<int, &getCoolNumber>(); //42 
} 

此代碼(http://cpp.sh/,如果你想嘗試一下),但是因爲我給一個函數指針作爲模板參數我不應該需要_returnType,這是正確的,在函數簽名,問題是,不管我多努力嘗試,我都找不到一種方法來擺脫這個額外的模板參數。

我該如何讓aliasGetter只接受一個模板參數(指向getter指向別名的指針)? 如果這是不可能的,爲什麼不呢?

+0

如何使用單個模板參數並依賴模板參數扣除? – WhiZTiM

+1

@WhiZTiM這需要在運行時將函數指針傳遞給調用。 –

+0

您需要它,因爲您的第二個模板參數依賴於它。你可以用https://functionalcpp.wordpress.com/2013/08/05/function-traits/建立一些東西,但我懷疑你會保存一個模板參數。 – knivil

回答

14

在C++ 17,這將成爲可能,這要歸功於template auto

template <auto F> std::invoke_result_t<F> aliasGetter() { return F(); } 

之前C++ 17,這是不可能的。您需要指定非類型模板參數的類型 - 這是沒有辦法的。您無法爲此創建工廠,因爲您無法通過函數模板傳遞函數指針,並將其作爲非類型模板參數傳遞。


在C++ 14的最短的解決方法是,嘆息,使用宏:

template <class T, T F> std::result_of_t<T()> aliasGetter() { return F(); } 
#define TEMP_ALIAS(x) decltype(x), x 

std::cout << aliasGetter<TEMP_ALIAS(&getCoolNumber)>(); 

它可以讓你的函數指針的類型,您無需手動輸入兩次。

+1

我知道使用C + 17可能會感謝您所描述的新語法,但是,我認爲也許它可以在沒有這種魔術的情況下完成(這就是爲什麼我標記了C++ 14)。雖然 – Nyashes

+0

C++ 17上的'std :: result_of'爲[deprecated](http://en.cppreference.com/w/cpp/types/result_of),但它仍然是一個很好且清晰的答案,請使用'std :: invoke_result相反。 –