不能用带有特定构造函数的对象来创建由不可移动、不可拷贝对象组成的std::array
我想创建一个含有27个不可移动、不可拷贝对象的数组,然后对它们使用普通引用。
https://godbolt.org/z/zYhrTxK6c
带有不可拷贝、不可移动对象的Playground
class Object {
public:
explicit Object(std::size_t initial = 1) : value_(initial) {}
Object(const Object &) = delete;
Object(Object &&) = delete;
Object &operator=(const Object &) = delete;
Object &operator=(Object &&) = delete;
private:
std::size_t value_;
};
我的尝试:
template <size_t... Is>
auto create_semaphores_array_details(size_t concurrency_per_service,
std::index_sequence<Is...> /*unused*/)
{
return std::to_array(
{(Is, Object(concurrency_per_service))...});
};
template <size_t amount_of_services>
auto create_semaphores_array(size_t concurrency_per_service)
{
return create_semaphores_array_details(
concurrency_per_service,
std::make_index_sequence<amount_of_services>());
};
constexpr size_t amount_of_services
= 27;
std::array<Object, amount_of_services>
semaphores_per_services
= create_semaphores_array<amount_of_services>(
5);
简而言之,失败的原因是:
is_move_constructible失败
第二次尝试,和上面一样,只是把 std::experimental::make_array(...) 换成 std::to_array({...})。简而言之,它仍然失败,原因是:
使用已删除的Object(Object &&)
有什么办法能够构造出这样的对象并且能够改变对象的数量吗?
解决方案
你不能把不可移动的类型作为参数传给函数来构建那种类型。 C++17的拷贝消除对函数参数不起作用,因为参数是具名的左值。
你必须就地构造;可以用工厂来实现。 你可以使用类似下面的做法:
template <std::size_t N, typename F>
auto make_array_from_factory(F f) -> std::array<std::decay_t<decltype(f())>, N>
{
return [&]<std::size_t... Is>(std::index_sequence<Is...>){
return std::array<std::decay_t<decltype(f())>, N>{{(static_cast<void>(Is), f())...}};
}(std::make_index_sequence<N>());
}
然后
make_array_from_factory<42>([&](){ return Object(concurrency_per_service); });
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。