ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – vector>使用初始化列表

2019-07-24 13:08:59  阅读:165  来源: 互联网

标签:c c11 containers constructor unique-ptr


我有一个错误:调用’std :: __ 1 :: unique_ptr>’的隐式删除的复制构造函数当编译代码类似于下面的使用
c -std = c 14 unique_ptr_vector.cpp -o main

这是一个简化版本:

头文件’my_header.h’:

#include <iostream>
#include <string>
#include <memory>
#include <vector>

class A{
public:
    A() : n(0) {}
    A(int val) : n(val) {} 
    A(const A &rhs): n(rhs.n) {}
    A(A &&rhs) : n(std::move(rhs.n)) {}
    A& operator=(const A &rhs) { n = rhs.n; return *this; }
    A& operator=(A &&rhs) { n = std::move(rhs.n); return *this; }
    ~A() {}

    void print() const { std::cout << "class A: " << n << std::endl; }
private:
    int n;
};

namespace {
    std::vector<std::unique_ptr<A>> vecA = {
        std::make_unique<A>(1),
        std::make_unique<A>(2),
        std::make_unique<A>(3),
        std::make_unique<A>(4)
    };
}

我的src文件’unique_ptr_vector.cpp’:

#include "my_header.h"

using namespace std;

int main()
{
    for(const auto &ptrA : vecA){
        ptrA->print();
    }
    return 0;
}

我是否真的需要为每个组件单独使用push_back(std :: make_unique()),
或者在标题中填充容器的首选方法是什么?或者一般来说这是个坏主意吗?

我见过像this one,this onethis one这样的问题.

我知道现在初始化列表似乎不可能.但是人们通常用容器< unique_ptr>做什么.我应该只是避免在标题中初始化…

解决方法:

初始化列表是const数组的包装器.

const的unique_ptrs无法移动.

我们可以这样(以完全合法的方式)解决这个问题:

template<class T>
struct movable_il {
  mutable T t;
  operator T() const&& { return std::move(t); }
  movable_il( T&& in ): t(std::move(in)) {}
};

template<class T, class A=std::allocator<T>>
std::vector<T,A> vector_from_il( std::initializer_list< movable_il<T> > il ) {
  std::vector<T,A> r( std::make_move_iterator(il.begin()), std::make_move_iterator(il.end()) );
  return r;
}

Live example.

使用:

auto v = vector_from_il<int>({
  std::make_unique<int>(7), 
  std::make_unique<int>(3)
});

如果你想知道为什么初始化器列表引用const数据,你必须追踪并阅读委员会会议记录或询问那里的人.我猜它是关于最少惊喜的原则和/或有关于可变数据和视图类型的bugaboos的人(例如将array_view重命名为span).

如果你想要的不仅仅是矢量:

template<class C, class T=typename C::value_type>
C container_from_il( std::initializer_list< movable_il<T> > il ) {
  C r( std::make_move_iterator(il.begin()), std::make_move_iterator(il.end()) );
  return r;
}

因为我们还想移动键,所以仍然需要使用关联容器进行按摩.

template<class VT>
struct fix_vt {
  using type=VT;
};
template<class VT>
using fix_vt_t = typename fix_vt<VT>::type;
template<class VT>
struct fix_vt<const VT>:fix_vt<VT>{};
template<class K, class V>
struct fix_vt<std::pair<K,V>>{
  using type=std::pair<
    typename std::remove_cv<K>::type,
    typename std::remove_cv<V>::type
  >;
};

template<class C, class T=fix_vt_t<typename C::value_type>>
C container_from_il( std::initializer_list< movable_il<T> > il ) {
  C r( std::make_move_iterator(il.begin()), std::make_move_iterator(il.end()) );
  return r;
}

标签:c,c11,containers,constructor,unique-ptr
来源: https://codeday.me/bug/20190724/1522347.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有