簡體   English   中英

如何在c ++中存儲可變參數模板參數?

[英]How to store variadic template parameters in c++ ?

我想將派生類的可變參數模板參數(一組整數)傳遞給另一個模板化類。 我無法修改第二個類,因為它是libary的一部分。

我已經弄清楚如何在編譯時存儲這些參數(例如常量數組或整數序列),但我不知道如何將這些結構傳遞給庫類。 解決方案可能很明顯但我現在已經失去了處理這種可變參數的所有可能性。

我試圖建立一個簡單的例子來更好地解釋我的問題:

// Example program
#include <iostream>
#include <array>
#include <utility>


// this class has some compile time paramters
template <int... N>
class BaseClass
{
  public:
  BaseClass(){};
  ~BaseClass(){};

   //one idea to store the parameters using a compile time array 
   static constexpr std::array<int, sizeof...(N)> _N = {{N...}};

   //another idea using a integer sequence type
   using _Ni = std::integer_sequence<int, N...>;
};

// this special case of BaseClass hast the parameter 5,6,7,8
class SpecialClass:public BaseClass<5,6,7,8>
{
  public:
  SpecialClass(){};
  ~SpecialClass(){};
};


// this class is fixed and can not be modified because it's part of an libary
template <int... N>
class Printer
{
    public:
    Printer(){};
    ~Printer(){};

    // it can (for example) print its template parameters
    void print()
    {
        int dummy[sizeof...(N)] = { (std::cout << N, 0)... };
    }
};


int main()
{

  // this obviously works
  Printer <1,2,3,4> TestPrinter;
  TestPrinter.print();

  // this works not
  Printer <SpecialClass::_N> TestPrinterSpecialArray;
  TestPrinterSpecialArray.print();

  // this also works not
  Printer <SpecialClass::_Ni> TestPrinterSpecialSequence;
  TestPrinterSpecialSequence.print();

  return 0;
}

你可以編寫一個解包std::integer_sequence的輔助函數,

template<int... is>
auto make_printer_impl(std::integer_sequence<int, is...>)
{
    Printer<is...> printer;
    return printer;
}

template<class T>
auto make_printer()
{
    return make_printer_impl(typename T::_Ni{});
}

然后像這樣使用它:

auto TestPrinterSpecialSequence = make_printer<SpecialClass>();
TestPrinterSpecialSequence.print();

你可以為std::array成員做類似的事情:

template<class T, std::size_t... is>
auto make_printer_impl(std::index_sequence<is...>)
{
    Printer<T::_N[is]...> printer;
    return printer;
}

template<class T>
auto make_printer()
{
    return make_printer_impl<T>(std::make_index_sequence<T::_N.size()>{});
}

另請注意,保留以下划線后跟大寫字母開頭的標識符。 它們的使用會導致未定義的行為。 不要使用它們。

您可以創建幫助程序來執行此操作:

template <typename T, template <std::size_t...> class Other> struct remap;

template <template <std::size_t...> class Orig,
          std::size_t... Is,
          template <std::size_t...> class Other>
struct remap<Orig<Is...>, Other>
{
    using type = Other<Is...>;
};

template <typename T, template <std::size_t...> class Other>
using remap_t = typename remap<T, Other>::type;

接着

using SpecialClass = BaseClass<5,6,7,8>;

remap_t<SpecialClass, Printer> TestPrinterSpecialSequence; // Printer <5, 6, 7, 8>
TestPrinterSpecialSequence.print();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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