[英]Is it possible to have a "generic" template parameter in C++, that can be either a non-type template parameter or a type?
在 C++ 中,可以使用類型作為模板參數,例如:
template <typename T>
void MyFn();
在某些情況下,也可以使用非類型作為模板參數,例如:
template <int64_t T>
void MyFn2();
我的問題是是否有可能有一個“通用”模板參數可以是兩者? 喜歡:
template <TypenameOrint64_t T>
void MyFn3();
這樣MyFn3<42>
和MyFn3<double>
都是可以接受的。
我如何使用它的一個例子:
template <typename ValType, ValType Head, ValType ...Tail>
struct ListS{
template <typename OutType, template <ValType ArgType> class Fn>
using MapHead = ListS<OutType, Fn<Head>::val, Tail...>;
};
template<int64_t N>
struct SquareS{
static constexpr const int64_t val = N * N;
};
using Sqrd = ListS<int64_t, 3, 4>::MapHead<int64_t, SquareS>;
static_assert(std::is_same<Sqrd, ListS<int64_t, 9, 4>>::value, "Values don't match");
上面是一個非常粗略的編譯時值列表以及一個編譯時“函數”。 是否有可能使類似的東西也支持類型列表,而不僅僅是非類型模板參數兼容值的列表,而不僅僅是復制所有代碼?
在 C++ 中是否可以有一個“通用”模板參數,它可以是非類型模板參數或類型?
簡短的回答:沒有。
長答案。
不。我能想象的最好的混合類型和值是將值包裝在類型中,例如使用std::integral_constant
。
所以,你想要的代碼,幾乎可以寫成(C++17)如下
#include <utility>
template <typename ...>
struct ListS;
template <typename ValType, ValType Head, ValType ...Tail>
struct ListS<std::integral_constant<ValType, Head>,
std::integral_constant<ValType, Tail>...>
{
template <template <auto> class Fn, typename OutType = ValType>
using MapHead = ListS<std::integral_constant<OutType, Fn<Head>::value>,
std::integral_constant<OutType, Tail>...>;
};
template <auto N>
struct SquareS : public std::integral_constant<decltype(N), N*N>
{ };
int main ()
{
using T1 = ListS<std::integral_constant<long long, 3ll>,
std::integral_constant<long long, 4ll>>;
using T2 = T1::MapHead<SquareS>;
using T3 = ListS<std::integral_constant<long long, 9ll>,
std::integral_constant<long long, 4ll>>;
static_assert( std::is_same_v<T2, T3> );
}
在 C++17 之前,您不能將auto
用於模板值的類型,因此您應該進行一些簡單的更正。
您可以使用C++17
附帶的函數重載和auto
類型推導來完成類似的工作。
template<typename myType>
auto myFn3(myType value){
return value;
}
template<auto value> //takes any non-type parameter
auto myFn3(){
return value;
}
int main(){
auto test1_normal = myFn3(3);
auto test1_cast = myFn3<double>(3); //able to perform a cast
auto test1_auto = myFn3<3>();
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.