![](/img/trans.png)
[英]Declare template function to accept any container but only one contained type
[英]Can I declare a template to only accept functions with homogeneous signature?
我有一組雙重函數,每個函數接受N
個類型為T
的參數,第二個為X
類型。
對於N=2
, T=int
和X=std::vector<int>
,二元組將如下所示:
void my_function2(int x1, int x2) {}
void my_function2(int x1, int x2, std::vector<int> other) {}
我試圖編寫一個模板化的高階函數,並將第一個函數傳遞給該函數。
這將適用於N=2
:
template <typename R, typename T>
int my_hof(R(*param)(T, T)) { param(1,2); }
my_hof(&my_function2); // compiles
使param
簽名顯式很重要,因為否則模板實例化將由於“未解析的重載函數類型”而失敗。 關鍵是要消除my_function2()
的第二次重載。
我的問題是我無法想到將其推廣到N
。 我嘗試使用可變參數模板:
template <typename R, typename ...X>
struct make_signature { using type = R(*)(int, int); };
// Cheating a big on make_signature not to clutter the question
// But the idea would be to repeat the same type N times.
template <typename R, typename ...X>
int my_generalized_hof(typename make_signature<R, X...>::type param) {
f(1,2); // cheating a bit on the call too
}
my_generalized_hof(&my_function2); // does not compile
我猜編譯器會感到困惑,因為沒有直接給出param
的類型,它無法決定使用哪個重載來進行類型計算。 (“再次出現未解析的重載函數類型”)。 我認為它也將拒絕執行類型計算,因為它無法推斷R
的類型。
我想不出一種生成簽名的方法。
有可能用C ++編寫嗎?
(請注意,我知道可以通過在調用my_generalized_hof()
時將my_function2()
轉換為正確的類型來選擇重載,但是我想避免這種情況)
我提出以下make_signature
template <typename T, std::size_t>
using getType = T;
template <typename, typename, std::size_t N,
typename = std::make_index_sequence<N>>
struct make_signature;
template <typename R, typename T, std::size_t N, std::size_t ... Is>
struct make_signature<R, T, N, std::index_sequence<Is...>>
{ using type = R(*)(getType<T, Is>...); };
但是有一個問題:當你寫的時候
template <typename R, typename T, std::size_t N>
void my_generalized_hof (typename make_signature<R, T, N>::type param)
{
// do something with param
}
make<R, T, N>
部分處於無推論上下文中(在::
之前),因此無法從參數推導R
, T
和N
我的意思是...你不能打電話
my_generalized_hof(&my_function2);
您必須如下明確模板參數
// ...............VVVVVVVVVVVVVVV
my_generalized_hof<void, int, 2u>(&my_function2);
以下是完整的編譯示例
#include <utility>
#include <vector>
#include <type_traits>
void my_function2(int x1, int x2) {}
void my_function2(int x1, int x2, std::vector<int> other) {}
template <typename T, std::size_t>
using getType = T;
template <typename, typename, std::size_t N,
typename = std::make_index_sequence<N>>
struct make_signature;
template <typename R, typename T, std::size_t N, std::size_t ... Is>
struct make_signature<R, T, N, std::index_sequence<Is...>>
{ using type = R(*)(getType<T, Is>...); };
template <typename R, typename T, std::size_t N>
void my_generalized_hof (typename make_signature<R, T, N>::type param)
{
// do something with param
}
int main ()
{
my_generalized_hof<void, int, 2u>(&my_function2);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.