【问题标题】:Variadic template specialization in C++11C++11 中的可变参数模板特化
【发布时间】:2012-11-22 23:43:59
【问题描述】:

它已经实现了吗,因为它不能编译:(使用 gcc 4.7.2)

template <typename... Ts>
struct Foo {
    int foo() {
        return 0;
    }
};

template <>
struct Foo<int x, int y> {
    int foo() {
        return x * y;
    }
};

int main()
{
    Foo<2, 3> x;
    cout << x.foo() << endl; //should print 6
}

【问题讨论】:

  • 如果不编译,编译器在抱怨什么?
  • 可变参数模板早已在 gcc 中实现。如果您想检查功能支持:gcc.gnu.org/projects/cxx0x.html

标签: c++ templates c++11 g++ clang++


【解决方案1】:

你犯了一些错误。主模板需要类型,而不是 积分常数。您还尝试使用 整数常量,但您的部分专业化使用类型。

这更近了:

#include <iostream>

template <int... Ts>
struct Foo {
    int foo() {
        return 0;
    }
};

template <>
struct Foo<3, 2> {
  const int x = 3;
  const int y = 2;

  int foo() {
    return x * y;
  }
};

int main()
{
    Foo<2, 3> x;
    std::cout << x.foo() << std::endl; //should print 6
}

但这并不是我们真正想要的,对吧?而且还很笨拙。

#include <iostream>

template<typename Acc, typename... Rest>
struct accum_help; // primary

template<typename Acc, typename F, typename... Rest>
struct accum_help<Acc, F, Rest...> {
  typedef typename accum_help<
    std::integral_constant<typename Acc::value_type, 
                           Acc::value * F::value>, Rest...
    >::type type;
};

template<typename Acc>
struct accum_help<Acc> {
  typedef Acc type;
};

// peek into the first argument to avoid summing empty sequences and
// get the right type
template<typename X, typename... Integrals>
struct accum {
  typedef typename accum_help<
    std::integral_constant<typename X::value_type, 1>, X, Integrals...
    >::type type;
};

int main()
{

  std::cout << accum< std::integral_constant<int, 2>, std::integral_constant<int, 3> >::type::value << std::endl; //should print 6
}

只处理 int 的更简单的变体:

template <int...>
struct accum2_help;

template <int Acc, int X, int... Rest> 
struct accum2_help<Acc, X, Rest...> {
  static const int value = accum2_help< Acc * X, Rest...>::value;
};

template <int Acc>
struct accum2_help<Acc> {
  static const int value = Acc;
};

// again don't accept empty packs
template <int T, int... Ts>
struct accum2 {
  static const int value = accum2_help<1, T, Ts...>::value;
};

【讨论】:

  • 那么如何做到这一点: 1. 声明&lt;int,int&gt; 版本的Foo 并用常量&lt;2, 3&gt; 实例化它?
  • Foo&lt;2, 3&gt; x?不应该是Foo&lt;3, 2&gt; x吗?
  • @Martin 如果您希望能够将Foo 用作Foo&lt;2, 3&gt;,那么看起来您想要的主模板类似于template&lt;int... I&gt; struct Foo;。
  • @martin 我添加了一个进行乘法运算的通用累加器。您仍然可以从中获得几个抽象级别,但它显示了一般主题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-15
  • 2016-12-25
  • 1970-01-01
  • 1970-01-01
  • 2015-11-10
相关资源
最近更新 更多