在编译时生成一系列的零

我有以下问题:

template< size_t... N_i > class A { public: // ... void foo() { bar( /* 0,...,0 <- sizeof...(N_i) many */); } }; 

我想调用一个函数bar ,并将sizeof...(N_i)parameter passing给它全部为零,例如,在sizeof...(N_i) == 3情况下, bar(0,0,0) 。 这怎么能被执行?

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

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

尽pipe@Columbo毫无疑问有趣的答案 ,我想build议另一个可行的解决scheme,基于constexpr模板variables:

  #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(); } 

即使在编译时的性能方面不好,我发现至less可以轻松阅读。


你可以很容易地概括它,如下所示:

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

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

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

你也可以使用模板来模拟类似的东西。 这是一个非常基本的解决scheme,只会创build一个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参数大小相同的零的列表。 无可否认,界面略有不同。

有关完整示例,其中显示了栏接收的元素的值,请参阅此处: 现场示例