簡體   English   中英

在 C++ 中是否可以有一個“通用”模板參數,它可以是非類型模板參數或類型?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM