給定typename Tand int N,下面的模板化值會生成一個型別為空的函式指標:
int (*) (T_0, ..., T_N)
雖然代碼有效,但我不喜歡它使用Temp引導幫助程式污染命名空間 -Temp是必需的,因為型別不能括在括號中。例如,以下都不是有效的。
(int (*)((int))
((int (*)(int)))
(int (*)( (I,T)... ))
最后一個條目顯示了我想如何擴展T到N Ts 串列 - 這當然是無效的。由于逗號運算子,這是一個T依賴I但只有值的技巧。T
作為一種解決方法,我被迫創建模板化的一次性型別Temp以T依賴于int,或者在這種情況下,I. 它的用法Temp<T,I>是有效的,因為它沒有將型別括在括號中。
但是,就像我說的,我想擺脫它,Temp因為它污染了命名空間。在下面的代碼中,我重申了問題并演示了一些嘗試的變通方法,但遺憾的是,它們都失敗了。作為記錄,我認為應該允許template <typename T, int> using Temp = T;和之間的等價。template <... template<typename T1, int N1> typename Temp=T>
跟進:當我最初發布這個問題時,我并不確切知道為什么不允許使用額外的括號,我仍然不確定為什么我的一些嘗試失敗了。例如:
decltype(w<T,N>())...
result_of<w<T,N>()>::type...
我沒有看到型別周圍的任何括號!
#include <iostream>
#include <typeinfo>
// Problem, #1
// This is a one-shot helper than pollutes the namespace
template <typename T, int>
using Temp = T;
// Idea #1
// Make the one-shot helper actuall useful, where ... represents either
// type or non-type parameters.
// Result
// Not possible.
//template <typename T, ...>
//using Dependent = T;
// Idea #2
// Make the types dependent within the template declaration
// Result
// Probably not possible
//template <typename T, int N, template<typename T1, int N1> typename F=T>
// Idea #6
// Replace the lambda with a struct (not shown)
// Result
// Crashes gcc
template <typename T, int N>
auto a =
[]<size_t... I>
(std::index_sequence<I...>) {
// Problem #2
// Function type declaration won't parse with extra parentheses
//return (int (*)( (I,T)... ))nullptr;
// Idea #3
// Move the templated helper into the function
// Result
// Not possible
//template <typename T, int>
//using Temp = T;
// Idea #4
// Replace the templated helper with a templated lambda which *is*
// allowed inside functions.
// Result
// Still requires parentheses, still breaks function type declaration
//auto w = []<typename T1, int N1>() -> T1 {};
//return (int (*)( decltype(w<T,N>())... ));
// Idea #5
// result_of (which is a template) instead of decltype
// Result
// Doesn't work even without parentheses, not sure why
//return (int (*)( result_of<w<T,N>>... ));
//return (int (*)( result_of<w<T,N>()>::type... ));
// Idea #7
// Use std::function
// Result
// Can't get function pointer from std::function
// Idea #2 implementation
//using F<T,I> = T;
//return (int (*)( F<T,I>... ))nullptr;
// So far, only this works:
return (int (*)( Temp<T,I>... ))nullptr;
}
(std::make_index_sequence<N>{});
int main () {
auto b = a<int, 4>;
std::cout << typeid(b).name() << std::endl;
}
uj5u.com熱心網友回復:
您可以替換Temp<T,I>為std::enable_if_t<(void(I), true), T>.
函式型別宣告不會決議額外的括號
這確實有效!為什么?
型別不能用括號括起來。但是 的第一個引數enable_if_t是一個運算式而不是一個型別,所以( )在那里是允許的。
uj5u.com熱心網友回復:
使用Boost.Mp11這很容易:
template <typename... Args>
using into_func = int(Args...);
template <typename T, size_t N>
using result = mp_apply<func_type, mp_repeat_c<mp_list<T>, N>>;
mp_repeat_c<mp_list<T>, N>給我們引數mp_list<T, T, T, ..., T>,N然后我們mp_apply into_func就可以了,這把它變成了我們想要的函式型別。
至于為什么您的其他一些版本不起作用:
這個:
decltype(w<T,N>())...
在哪里:
auto w = []<typename T1, int N1>() -> T1 {};
這不是你所說的 lambda。呼叫運算子是一個模板,但您不能提供這樣的模板引數。你必須寫w.operator()<T, N>()。如果你這樣做了,那可能會奏效。
或者你可以這樣做:
auto w = [](size_t) -> T { };
然后使用decltype(w(N))....
雖然寫一些更接近有效 lambda 的東西會更好,比如:
auto w = [](size_t) { return std::type_identity<T>{}; };
然后使用typename decltype(w(N))::type...
這種方法:
result_of<w<T,N>()>::type...
result_of像result_of<F(Args...)>whereF是函式或函式物件型別一樣使用。例如:
struct F { double operator()(int); };
result_of_t<F(int)>; // this is double
這根本不是這樣的——這只是對result_of. result_of也棄用了invoke_result, 無論如何它都不能與指定的這個 lambda 一起作業,因為它再次采用模板引數而不是函式引數。
在我最后一次重寫時:
typename std::invoke_result_t<decltype(w), decltype(N)>::type...
注意decltype(w)(因為你需要一個型別,而不是一個物件)和decltype(N)(同樣,型別不是值)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/489103.html
