【问题标题】:How to initialize an std::array<T, 2> where T is non-copyable and non-default-constructible?如何初始化 std::array<T, 2> 其中 T 不可复制且不可默认构造?
【发布时间】:2016-07-29 01:59:47
【问题描述】:

我有固定数量的 T 类对象,这些对象不可复制且不可默认构造。由于大小是固定的,我想使用像std::array 这样的数组容器,而不是unique_ptrvector。如果可以的话,我想避免额外的间接层。

如何初始化std::array&lt;T, 2&gt;?使用array&lt;T, 2&gt; {T(...), T(...)} 会导致有关已删除复制构造函数的错误。使用array&lt;T, 2&gt; {move(T(...)), move(T(...))} 不会强制数组元素使用移动构造函数。如果std::array&lt;T, 2&gt; 本身不起作用,我还能做些什么而不求助于额外的间接层或像placement-new 这样的手动内存管理技术?

【问题讨论】:

  • 在我看来,所有的 T 实例都应该只能通过智能指针访问。 std::array 的唯一/共享 ptrs 到 T 等...
  • @SamVarshavchik,但是您可以将 std::vector 与仅移动、不可默认构造的类型一起使用。
  • 我想要完成的事情原则上可以完成,尽管使用诸如放置新的混乱和难以阅读的技术。我知道向量会很简单,但它给了我额外的开销,我打算避免原则上是完全可以避免的。
  • 你考虑过使用元组吗?
  • 我想访问带有索引的元素。

标签: c++


【解决方案1】:

不需要额外的东西,直接初始化即可:

class Foo {
public:
    Foo() = delete;
    Foo(int,char) {}

    Foo(Foo const &) = delete;
    Foo & operator = (Foo const &) = delete;
};
    std::array<Foo, 2> arr {{ {1, '1'}, {2, '2'} }};

DEMO

【讨论】:

【解决方案2】:

我的示例不是最好的,但它可以工作。只需创建一个 make_array 的函数并让它为您创建实例..

http://ideone.com/fxAO3t

#include <array>
#include <iostream>

class Foo
{
    public:
        Foo(int)
        {

        }

        Foo(const Foo &) = delete;

        Foo(Foo &&)
        {
            std::cout<<"Moved\n";
        }
};

template<class... Type>
constexpr std::array<typename std::common_type<Type...>::type, sizeof...(Type)> make_array(Type&&... t)
{
    return {std::forward<Type>(t)...};
}

int main() {
    auto arr = make_array(Foo{1}, Foo{2});
    return 0;
}

正如 cmets 中指出的,您可以使用std::array&lt;Foo, 2&gt; arr = {Foo{1}, Foo{2}}

我注意到您在帖子中尝试move。你确定你的班级是moveable吗?

【讨论】:

  • 如果Foo 是可移动的,则不需要该功能。只需std::array&lt;Foo, 2&gt; arr{1, 2}; 就足够了。
  • 啊,你是对的。 OP 正试图完全按照您的建议进行操作。他/她在做std::move(Foo)
猜你喜欢
  • 2018-10-04
  • 1970-01-01
  • 2016-10-18
  • 1970-01-01
  • 2012-02-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多