为什么我不能使用{std :: move(first),std :: move(second)}实例化std :: vector <std :: unique_ptr <int >>?

时间:2019-02-15 13:06:54

标签: c++ unique-ptr initializer-list

我有一个简单的函数,该函数应该构造一些对象并返回它们的向量,同时还要转移所有权。我认为最好的方法是简单地返回std::vector<std::unique_ptr<int>>个对象(假设它们是int)。

当我尝试以下功能时:

std::vector<std::unique_ptr<int>> create_stuff() {
    auto first = std::make_unique<int>(1);
    auto second = std::make_unique<int>(2);
    return {std::move(first), std::move(second)};
}

我受到一个非常长的编译错误的欢迎,结尾为:

xmemory0(737): error C2280: 'std::unique_ptr<int,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)':
attempting to reference a deleted function

我认为问题出在函数本身,但是以下解决方案效果很好:

std::vector<std::unique_ptr<int>> create_stuff() {
    auto first = std::make_unique<int>(1);
    auto second = std::make_unique<int>(2);
    std::vector<std::unique_ptr<int>> results;
    results.push_back(std::move(first));
    results.push_back(std::move(second));
    return results;
}

为什么第二个解决方案有效,但第一个解决方案无效?有没有一种解决方法可以使我在初始化列表中使用简短的语法?

2 个答案:

答案 0 :(得分:3)

  

为什么第二个解决方案有效,而第一个解决方案无效?

您使用的列表初始化语法调用接受std::initializer_list的构造函数。 std::initializer_list不可移动,std::initializer_list<std::unique_ptr<T>>不可复制,因此无法调用构造函数。

在后一个示例中,您使用默认的构造函数,因此没有问题。

  

有没有一种解决方法可以让我在初始化列表中使用简短的语法?

您可以列出初始化数组,并使用一对移动迭代器:

std::array arr{
    std::make_unique<int>(1),
    std::make_unique<int>(2),
};
return std::vector(
    std::make_move_iterator(std::begin(arr)),
    std::make_move_iterator(std::end(arr))
);

有一个proposal使std::initializer_list可以移动,但是尚未被采用(尚未被采用;谁知道未来会带来什么)。

答案 1 :(得分:1)

在我的平台上,相关代码为:

cols = ['made_profit', 'profit_amount']
def product0_makes_profit(row, product0_cost):
    return pd.Series([row['sold_for'] > product0_cost, row['sold_for'] - product0_cost], index=cols)

def product1_makes_profit(row, product1_cost):
    return pd.Series([row['sold_for'] > product1_cost, row['sold_for'] - product1_cost], index=cols)

for c in cols:
    df_test[c] = np.nan

is_prod0 = (df_test['product']==0)
df_test.loc[is_prod0, cols] = df_test[is_prod0].apply(product0_makes_profit, args=[4000], axis=1, result_type="expand")
is_prod1 = (df_test['product']==1)
df_test.loc[is_prod1, cols] = df_test[is_prod1].apply(product1_makes_profit, args=[9000], axis=1, result_type="expand")
print(df_test)

   product  sold_for  made_profit  profit_amount
0        0      5000         True         1000.0
1        0      4500         True          500.0
2        1     10000         True         1000.0
3        1      8000        False        -1000.0

vector(initializer_list<value_type> __l, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_range_initialize(__l.begin(), __l.end(), random_access_iterator_tag()); } 只需从迭代器中复制,而不是从其移出。