简体   繁体   English

如何有效地在向量中插入多个可复制但不可复制的元素?

[英]How to efficiently insert multiple copy-constructible but not copy-assignable elements in a vector?

I have a type X , which is copy-constructible but not copy assignable我有一个类型X ,它是可复制构造但不可复制分配的

struct X {
    X();
    X(const X&);
    X& operator=(const X&) = delete; // !!
    X(X&&) noexcept;
    X& operator=(X&&) noexcept;
    int data = 54;
};

I have two vectors of 'X': a and b and I want to insert all the contents of b at the front of a :我有两个 'X' 向量: ab ,我想在 a 的前面插入b的所有a

void add_to_front(std::vector<X>& a, const std::vector<X>& b) {
    a.insert(a.begin(), b.begin(), b.end());
}

This compiles and works as expected on msvc but fails to compile on clang and gcc.这可以在 msvc 上按预期编译和工作,但无法在 clang 和 gcc 上编译。 I'm guessing due to poor implementations of libc++ and libstdc++ which need something to compile even though it will never get called (or, worse yet, it will get called?.).我猜是由于 libc++ 和 libstdc++ 的糟糕实现需要一些东西来编译,即使它永远不会被调用(或者,更糟糕的是,它会被调用?.)。

I could write a manual loop to emplace elements of b into a which will produce a correct result, but the complexity of this is a*b instead of a+b, as each call to emplace will shift all elements of a over and over again.我可以编写一个手动循环来将b的元素放置到a中,这将产生正确的结果,但它的复杂性是 a*b 而不是 a+b,因为每次调用emplace都会一遍又一emplace移动a所有元素.

So is there an efficient way to do it?那么有没有一种有效的方法呢?

Live demo can be found here现场演示可以在这里找到

I must admit that I'm not quite sure whether the poor implementations of libc++ and libstdc++ are the issue.我必须承认,我不太确定libc++ 和 libstdc++ 的糟糕实现是否是问题所在。 Though, I found a quite simple way to circumvent OPs issue:不过,我找到了一种非常简单的方法来规避 OPs 问题:

#include <vector>

struct X {
    X() = default;
    X(const X&) = default;
    X& operator=(const X&) = delete; // !!
    X(X&&) noexcept = default;
    X& operator=(X&&) noexcept = default;
    int data = 54;
};

void add_to_front(std::vector<X>& a, const std::vector<X>& b) {
    std::vector<X> b_(b);
    a.insert(a.begin(), std::make_move_iterator(b_.begin()), std::make_move_iterator(b_.end()));
}

int main()
{
  std::vector<X> a, b;
  add_to_front(a, b);
}

This is accepted by这被接受

  • clang 11.0.0 -std=c++11 -O2 clang 11.0.0 -std=c++11 -O2
  • gcc 9.2 -std=c++11 -O2 gcc 9.2 -std=c++11 -O2
  • msvc 19.28 /std:c++14 /O2 msvc 19.28 /std:c++14 /O2

Live Demo on Compiler Explorer Compiler Explorer 上的现场演示


@Evg had a look into the @Evg查看了
Type requirements for std::vector::insert() std::vector::insert() 的类型要求

In OPs case it's this overload:在 OPs 的情况下,这就是重载:

 template< class InputIt > iterator insert( const_iterator pos, InputIt first, InputIt last );

with

  • T must meet the requirements of EmplaceConstructible in order to use overload (4,5). T 必须满足 EmplaceConstructible 的要求才能使用重载 (4,5)。
  • T must meet the requirements of MoveAssignable and MoveInsertable in order to use overload (4). T 必须满足 MoveAssignable 和 MoveInsertable 的要求才能使用重载 (4)。 required only if InputIt satisfies LegacyInputIterator but not LegacyForwardIterator.仅当 InputIt 满足 LegacyInputIterator 但不满足 LegacyForwardIterator 时才需要。

This should be granted by OPs struct X .这应该由 OPs struct X授予。

So, to me, it looks like OP is right with the complaints.所以,对我来说,看起来 OP 对这些投诉是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C++:如何将模板类型限制为可复制分配的类型? - c++: how to constrain template type to copy-assignable types? SFINAE - 如果 arguments 是可复制构造的,则启用一个 function,否则启用另一个 - SFINAE - enable one function if arguments are copy-constructible and another otherwise 为什么std :: function本身是一个可复制构造的类型? - Why is std::function itself a copy-constructible type? 是否可以检查抽象 class 是否是可复制构造的,忽略抽象性? - Is it possible to check if an abstract class is copy-constructible, ignoring abstractness? 即使我实现了副本分配运算符,类还是可以移动构造和分配的 - Class is move constructible and assignable even if I implement a copy assignment operator 如何有效地将std :: string复制到向量中 - How to efficiently copy a std::string into a vector 可以利用is_trivially_copy_assignable和is_trivially_copy_constructible进行优化吗? - Can is_trivially_copy_assignable and is_trivially_copy_constructible be exploited for optimization purposes? 向量上的 is_copy_constructible 误报<unique_ptr></unique_ptr> - False positive with is_copy_constructible on vector<unique_ptr> std :: vector emplace_back()用于非复制可构造对象 - std::vector emplace_back() for non copy constructible objects 如何在c ++中将向量的元素复制到堆栈 - How to copy elements of a vector to a stack in c++
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM