我最初的目標是消除以下歧義:
template<typename... T, typename... U>
void foo(){}
在這種情況下,foo< <a_sequence_of_types> >()總是導致T = <a_sequence_of_types>and U = <empty_parameter_pack>。
一個經典的解決方案是分別打包T...和U...放入std::tuple<T...>并std::tuple<U...>使用這些型別作為 foo 中的默認引數。
template<typename... T, typename... U>
void foo(std::tuple<T...>, std::tuple<U...>){}
如果任何涉及的模板引數不是默認可構造的,則會出現問題,因為在這種情況下無法系結 foo 的虛擬引數。
然后我開始尋找一個標準的、慣用的模板引數包包裝器,但沒有運氣。一個錯誤的希望是std::index_sequence_for不啟用模板引數包推導,因為它只是std::integer_sequence洗掉其模板型別引數包的模板別名。
我最終使用了自己的包裝器
template<typename... T>
struct TypePack{};
template<typename... T, typename... U>
void foo(TypePack<T...>, TypePack<U...>){}
它是普通的 constexpr 默認可構造的,并且像一個魅力一樣代替 std::tuple。但它缺乏標準型別在以慣用方式使用時提供的清晰度。有沒有這樣更慣用的方式?
注意:這是我的代碼庫實作的一部分,最終用戶看不到。請不要從 API 設計的角度來解決這個問題。那時我對自記錄代碼更感興趣。
uj5u.com熱心網友回復:
如果任何涉及的模板引數不是默認可構造的,則會出現問題,因為在這種情況下無法系結 foo 的虛擬引數。
您可以通過std::type_identity<T>而不是T元組來傳遞型別:
foo(std::tuple<std::type_identity<int&>,
std::type_identity<const float&>>{},
std::tuple<std::type_identity<void>>{});
另一種可能性是分成foo兩部分:
template <typename... Ts>
struct foo_t
{
template <typename... Us>
static void foo() {/*...*/}
};
用法類似于
foo_t<int&, const float&>::foo<void>();
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/515141.html
上一篇:錯誤:std::variant的模板引數串列中的型別/值不匹配
下一篇:定義函式引數數量的C 模板
