<html>
<head>
<base href="https://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW --- - std::vector incorrectly requires CopyConstructible, Destructible and other concepts"
href="https://llvm.org/bugs/show_bug.cgi?id=28412">28412</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>std::vector incorrectly requires CopyConstructible, Destructible and other concepts
</td>
</tr>
<tr>
<th>Product</th>
<td>libc++
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>All
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>All Bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>zilla@kayari.org
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>Container requirements are all stated in terms of CopyInsertable into X, and
Erasable from X, which involves indirection through the container's allocator.
The following test shows a class which can only be constructed/destroyed by its
allocator, revealing that std::vector tries to construct temporaries directly
without going through the allocator.
/usr/local/libcxx-head/include/c++/v1/vector:1815:24: error: call to deleted
constructor of 'value_type' (aka 'X')
#include <vector>
struct Tag { };
template<typename T>
class TaggingAllocator
{
public:
using value_type = T;
TaggingAllocator() = default;
template<typename U>
TaggingAllocator(const TaggingAllocator<U>&) { }
T*
allocate(std::size_t n) { return std::allocator<T>{}.allocate(n); }
void
deallocate(T* p, std::size_t n) { std::allocator<T>{}.deallocate(p, n); }
template<typename U, typename... Args>
void
construct(U* p, Args&&... args)
{ ::new((void*)p) U(Tag{}, std::forward<Args>(args)...); }
template<typename U, typename... Args>
void
destroy(U* p)
{ p->~U(); }
};
template<typename T, typename U>
bool
operator==(const TaggingAllocator<T>&, const TaggingAllocator<U>&)
{ return true; }
template<typename T, typename U>
bool
operator!=(const TaggingAllocator<T>&, const TaggingAllocator<U>&)
{ return false; }
struct X
{
// All constructors must be passed the Tag type.
// DefaultInsertable into vector<X, TaggingAllocator<X>>,
X(Tag) { }
// CopyInsertable into vector<X, TaggingAllocator<X>>,
X(Tag, const X&) { }
// MoveInsertable into vector<X, TaggingAllocator<X>>, and
X(Tag, X&&) { }
// EmplaceConstructible into vector<X, TaggingAllocator<X>> from args.
template<typename... Args>
X(Tag, Args&&...) { }
// not DefaultConstructible, CopyConstructible or MoveConstructible.
X() = delete;
X(const X&) = delete;
X(X&&) = delete;
// CopyAssignable.
X& operator=(const X&) { return *this; }
// MoveAssignable.
X& operator=(X&&) { return *this; }
private:
// Not Destructible.
~X() { }
// Erasable from vector<X, TaggingAllocator<X>>.
friend class TaggingAllocator<X>;
};
int main()
{
std::vector<X, TaggingAllocator<X>> v;
v.reserve(3);
v.emplace_back();
v.emplace(v.begin());
v.emplace(v.begin(), 1, 2, 3);
}
// template class std::vector<X, TaggingAllocator<X>>;
Uncommenting the last line to explicitly instantiate the vector fails
differently, presumably there are some SFINAE conditions which make invalid
assumptions about the type.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>