如何解决我如何构造一个填充有一些统一值的std :: array?
可以构造具有特定值的 std::array
(在编译时使用较新的C ++版本),例如
std::array a{1,4,9};
但是-它没有构造函数,也没有标准的库,称为构造函数的惯用语,它只取一个值并将其复制。即我们没有:
std::array<int,3> a{11};
// a == std::array<int,3>{11,11,11};
因此,我们如何构造仅给出要重复的值的数组?
编辑:我正在寻找一种解决方案,该解决方案甚至适用于无法默认构造的元素类型;因此,我不需要的是通过默认构造数组然后填充它的解决方案-尽管事实上这对于int
来说是有效的(如示例中所示)。
解决方法
我们可以编写一个合适的named constructor idiom来实现这一目标
该实现有些笨拙,但是,由于我们需要使用"indices trick",在C ++ 11中需要大量样板,因此我们假设C ++ 14:
namespace detail {
template<size_t,class T>
constexpr T&& identity(T&& x) { return std::forward<T>(x); }
template<class T,size_t... Indices>
constexpr auto array_repeat_impl(T&& x,std::index_sequence<Indices...>)
{
return std::experimental::make_array(identity<Indices>(x)...);
}
} // end detail
template<size_t N,class T>
constexpr auto array_repeat(T&& x)
{
return detail::array_repeat_impl(std::forward<T>(x),std::make_index_sequence<N>());
}
请参见GodBolt上的内容。
如果可以编译C ++ 20代码,则可以删除对make_array
的依赖关系并编写:
namespace detail {
template<size_t,std::index_sequence<Indices...>)
{
return std::array{identity<Indices>(x)...};
}
} // end detail
template<size_t N,std::make_index_sequence<N>());
}
注意:
- 此解决方案有点类似于Jared Hoberock的tuple utilities for C++11的
tuple_repeat
。 - 感谢@Caleth和@ L.F。在
array_repeat_impl
中指出不适当的转发。
使用C ++ 20,当类型是默认可构造且可复制的类型时,可以使用now-constexpr fill
函数(live example)直接为此提供帮助:
#include <array>
#include <concepts>
#include <cstddef>
template<std::size_t N,std::semiregular T>
constexpr auto array_repeat(const T& value) -> std::array<T,N> {
std::array<T,N> ret;
ret.fill(value);
return ret;
}
int main() {
constexpr auto a = array_repeat<3>(11);
static_assert(a == std::array<int,3>{11,11,11});
}
这可能效率较低,但是这是否取决于您。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。