在编译时生成一系列的零
我有以下问题:
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参数大小相同的零的列表。 无可否认,界面略有不同。
有关完整示例,其中显示了栏接收的元素的值,请参阅此处: 现场示例