在编译时生成一系列零

时间:2016-10-24 12:28:07

标签: c++ c++14 variadic-templates

我有以下问题:

template< size_t... N_i >
class A
{
  public:

    // ...

    void foo()
    {
      bar( /* 0,...,0 <- sizeof...(N_i) many */);
    }
};

我想调用函数bar并向sizeof...(N_i)传递许多参数,这些参数都是零,例如bar(0,0,0) sizeof...(N_i) == 3。 如何实施?

3 个答案:

答案 0 :(得分:61)

bar(((void)N_i, 0)...);

逗号运算符将丢弃N_i,只产生右侧操作数的值(0)。演员表是为了防止警告N_i被丢弃。

答案 1 :(得分:8)

尽管毫无疑问有趣answer by @Columbo,但我想建议另一种基于constexpr d模板变量的可行解决方案:

 #include <cstddef> 

 template<std::size_t, std::size_t V>
 constexpr std::size_t repeat_value = V;

 template<std::size_t... N_i>
 class A {
     template<typename... Args>
     void bar(Args&&...) { }

 public:   
      void foo() {
           // repeat N_i times value 0
           bar(repeat_value<N_i, 0>...);
      }
 };

 int main() {
      A<0, 1, 2, 3, 4> a;
      a.foo();
 }

我觉得至少更容易阅读,即使它在编译时的性能方面也不好。

您可以轻松地将其概括为:

template<std::size_t, typename T, T V>
constexpr T repeat_value = V;

具体情况下的调用是这样的:

bar(repeat_value<N_i, int, 0>...);

答案 2 :(得分:2)

您还可以使用模板来模拟类似的东西。这是一个非常基本的解决方案,只会创建一个0的列表,但如果需要,可以扩展它以生成其他序列。

template <size_t Unused>
struct Wrap {
  static constexpr size_t value = 0;
};

template <size_t... N_i>
class A {
public:
    void foo() {
        bar(Wrap<N_i>::value...);
    }
};

这将扩展为与N_i参数大小相同的零列表。不可否认,界面略有不同。

有关完整示例的详细示例,请参见此处:Live example