我有一个类模板,它基于模板参数构建一个简单的数组作为其成员之一.我需要能够将数组中的每个元素初始化为其中一个构造函数中的单个值.不幸的是,这个构造函数必须是constexpr.
相关部分归结为:
template <typename T,size_t N> class foo { T data[N]; constexpr foo(T val) { // initialize data with N copies of val } };
使用std :: fill或循环与constexpr要求不兼容.初始化:data {val}仅设置数组的第一个元素,并对剩余部分进行零初始化.
怎么能实现这一目标?
我觉得应该有一个可变参数模板和元组等的解决方案……
解决方法@H_301_14@
非常奇怪的是,问题的解决方案存在于c 14中(在gcc上使用-std = c 1y编译示例;另请参阅Praetorian的更详细的c 11解决方案的注释):
template <size_t N>
struct bar {
template <typename T,typename ...Tn>
static constexpr auto apply(T v,Tn ...vs)
{
return bar<N - 1>::apply(v,v,vs...);
}
};
template <>
struct bar<1> {
template <typename T,Tn ...vs)
{
return std::array<T,sizeof...(vs) + 1>{v,vs...};
}
};
template <typename T,size_t N>
struct foo {
std::array<T,N> data;
constexpr foo(T val)
: data(bar<N>::apply(val))
{}
};
(我用std :: array替换了POD数组 – 假设它不会对你的用例造成任何问题).
template <size_t N> struct bar { template <typename T,typename ...Tn> static constexpr auto apply(T v,Tn ...vs) { return bar<N - 1>::apply(v,v,vs...); } }; template <> struct bar<1> { template <typename T,Tn ...vs) { return std::array<T,sizeof...(vs) + 1>{v,vs...}; } }; template <typename T,size_t N> struct foo { std::array<T,N> data; constexpr foo(T val) : data(bar<N>::apply(val)) {} };
(我用std :: array替换了POD数组 – 假设它不会对你的用例造成任何问题).