【问题标题】:Functions with variadic templates带有可变参数模板的函数
【发布时间】:2012-01-09 18:59:07
【问题描述】:

我想写一个函数模板,它可以接受可变数量的模板参数,并且只打印出类型参数的 typeid().name()。我可以使用类模板中的静态函数来做类似的事情,如下所示:

template<typename...>
struct foo;

template<typename H, typename... T>
struct foo<H, T...> {
  static void print() {
    std::cout << typeid(H).name() << ", ";
    foo<T...>::print();
  }
};

template<typename H>
struct foo<H> {
  static void print() {
    std::cout << typeid(H).name() << "\n";
  }
};

int main(void)
{
  foo<int, float>::print();
  return 0;
}

但是,我无法执行以下操作:

template<typename H, typename... T>
void print() {
  std::cout << typeid(H).name() << ", ";
  print<T...>();
}
int main(void)
{
  print<int, float>();
  return 0;
}

我尝试添加以下“基本”案例:

template<typename H>
void print();

void print();

都没有用。这样的函数模板怎么写?

【问题讨论】:

  • 你收到了什么错误信息?
  • 您的课程模板专业化不明确。

标签: c++ templates c++11


【解决方案1】:

FWIW,我可以使用 Clang 3.1 和 GCC 4.5.1 编译以下代码:

#include <typeinfo>
#include <iostream>

template<class T>
void print(){
  std::cout << typeid(T).name();
}

template<typename H, typename T, typename... R>
void print(){
  std::cout << typeid(H).name() << ", ";
  print<T, R...>();
}

int main(){
  print<int, float>();
}

【讨论】:

  • 是的,这行得通。我没有想到在主要情况下处理 2 个或更多模板参数,在基本情况下处理 1 个参数是正确的解决方案。我试图在一般情况下做 1 个或更多,在基本情况下做 0 个。至少对我来说,主要的收获是 typename... A 匹配 0 个或多个参数。
【解决方案2】:
template<typename H>
void print();

这不起作用,因为它与可变参数重载不明确:两者都可以使用单个模板参数调用。

void print();

这不起作用,因为在您的可变参数 print 中,您调用的 print&lt;T...&gt; 只能匹配 print 模板,而不是常规函数(即使 T... 扩展为空参数列表,电话将是print&lt;&gt;(),而不是print()。)

一种解决方案是将可变参数大小写更改为仅接受至少两个参数:

template<typename H, typename T1, typename... TRest>
void print() {
  std::cout << typeid(H).name() << ", ";
  print<T1, T...>();
}

现在您的单参数print 模板应该在递归底部正确选择。

认为以下应该在 C++11 中作为零参数基本情况工作,但我无法让 gcc 4.6 接受它:

template<> void print();

【讨论】:

    【解决方案3】:

    您也可以这样做:

    void print() {/*...*/} 
    
    template<typename X>   void print() {/*...*/} 
    
    template<typename X, typename Y>   void print() {/*...*/} 
    
    int main()
    {
      print();
      print<int>();
      print<int,double>();
    
      return 0;
    }
    

    【讨论】:

    • 这不能处理超过 2 个模板参数。
    猜你喜欢
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 2012-05-03
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-20
    相关资源
    最近更新 更多