簡體   English   中英

可變參數模板解壓縮typename的參數

[英]variadic template unpacking arguments to typename

我想在func解壓縮參數包(參見第A行),但它不起作用。 如何在func <>內解包或僅修改A行?

#include <iostream>
using namespace std;

void func()
{
   cerr << "EMPTY" << endl;
}

template <class A, class ...B> void func()
{
   cerr << "A: "  << endl;
   func<B... >(); // line A
}


int main(void)
{
   func<int,int>();
   return 0;
}

預期輸出:

A:
A:

編輯:所有答案都非常好。 非常感謝

有時一次解壓縮所有內容更容易,而不是遞歸。 如果你只想要一個參數包for_each,你可以使用braced -init-list擴展技巧的變種( Coliru的現場演示 ):

template <class A>
void process_one_type() {
    cerr << typeid(A).name() << ' ';
}

template <class ...B> void func()
{
    int _[] = {0, (process_one_type<B>(), 0)...};
    (void)_;
    cerr << '\n';
}

通過使用func<B... >(); 你暗示func是一個函數模板,但你之前定義的func()不是。

您需要定義一個接受模板參數的func()模板。 這是一個工作示例(在g ++ 4.8.1上):

#include <iostream>
using namespace std;

void func()
{
   cerr << "EMPTY" << endl;
}

template <class ... B>
typename std::enable_if<sizeof...(B) == 0>::type func()
{
}

template <class A, class ...B> void func()
{
   cerr << "A: "  << endl;
   func<B... >(); // line A
}


int main(void)
{
   func();           // This outputs EMPTY
   func<int,int>();  // This will not output EMPTY
   return 0;
}

試試這個:

template <class A> void func()
{
    cerr << "A: " << endl;
}

template <class A, class B, class ...C> void func()
{
    cerr << "A: " << endl;
    func<B, C...>(); // line A
}

考慮一下遞歸調用func<B...>();的調用func<B...>(); 看起來像B...是空的。 它調用func<>(); 但是您嘗試的基本情況func()的定義不是模板函數,即。 你不能通過func<>();調用它func<>();

由於我們還沒有對函數模板進行部分特化,(希望很快就會支持),一種方法是使用類模板進行部分特化並使用函數將工作簡單地委托給類模板。

#include <iostream>

/* Forward declaration. */
template <typename... T>
struct FuncImpl;

/* Base case. */
template <>
struct FuncImpl<> {

  void operator()() const {
    std::cout << "Base case" << std::endl;
  }

};  // FuncImpl<>

/* Recursive case. */
template <typename First, typename... Rest>
struct FuncImpl<First, Rest...> {

  void operator()() const {
    std::cout << "Recursive case" << std::endl;
    FuncImpl<Rest...>()();
  }

};  // FuncImpl<First, Rest...>

/* Delegate function. */
template <typename... T>
void Func() {
  FuncImpl<T...>()();
}

int main() {
  Func<>();
  Func<int, double>();
}

我個人認為這個解決方案比其他解決方案更清晰,例如標記調度或SFINAE,盡管圍繞operator() s。

暫無
暫無

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

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