我有以下问题:
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
。
如何实施?
答案 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