简体   繁体   中英

Why does a constructor which takes iterators require elements to be EmplaceConstructible?

I have seen requirements for a sequence stl containers in the Standard (n4296), 23.2.3/4 (Table 100) and have read that a constructor which takes arguments-iterators (X - container, i and j - input iterators)

X(i, j)
X a(i, j)

requires a container's element type to be EmplaceConstructible.

Requires: T shall be EmplaceConstructible into X from *i

I think that a constructor can be implemented through calling std::allocator_traits::construct (m, p, *it) method for each iterator in range (where m - allocator of type A, p - pointer to memory, it - iterator in [i; j), and there is only CopyInsertable concept for elements is required because only one argument is provided for copying/moving, whereas EmplaceConstructible concept requires element to be constructed from a set of arguments. Is there any reasons for that decision?

CopyInsertable is a binary concept - given a container X it applies to a single type T , which is required to have a copy constructor. However, *i is allowed to be a different type from T , as long as there is a way to (implicitly) construct T from *i :

  char s[] = "hello world!";
  std::vector<int> v(std::begin(s), std::end(s));
  // int is EmplaceConstructible from char

A (contrived) example where T is not CopyInsertable :

struct nocopy {
  nocopy(int) {}
  nocopy(nocopy const&) = delete;
  nocopy(nocopy&&) = delete;
};
int a[]{1, 2, 3};
std::vector<nocopy> v(std::begin(a), std::end(a));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM