You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
struct Tag { };
template
class TaggingAllocator
{
public:
using value_type = T;
// template class std::vector<X, TaggingAllocator>;
Uncommenting the last line to explicitly instantiate the vector fails differently, presumably there are some SFINAE conditions which make invalid assumptions about the type.
The text was updated successfully, but these errors were encountered:
// template class std::vector<X, TaggingAllocator>;
Uncommenting the last line to explicitly instantiate the vector fails differently, presumably there are some SFINAE conditions which make invalid assumptions about the type.
The code that makes this blow up is in the SFINAE for assign:
X *p = new X(Tag());
v.assign(p, p + 1);
And this fails because is_constructible<X, X&>::value is false.
Extended Description
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
struct Tag { };
template
class TaggingAllocator
{
public:
using value_type = T;
};
template<typename T, typename U>
bool
operator==(const TaggingAllocator&, const TaggingAllocator&)
{ return true; }
template<typename T, typename U>
bool
operator!=(const TaggingAllocator&, const TaggingAllocator&)
{ return false; }
struct X
{
// All constructors must be passed the Tag type.
// DefaultInsertable into vector<X, TaggingAllocator>,
X(Tag) { }
// CopyInsertable into vector<X, TaggingAllocator>,
X(Tag, const X&) { }
// MoveInsertable into vector<X, TaggingAllocator>, and
X(Tag, X&&) { }
// EmplaceConstructible into vector<X, TaggingAllocator> 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>.
friend class TaggingAllocator;
};
int main()
{
std::vector<X, TaggingAllocator> v;
v.reserve(3);
v.emplace_back();
v.emplace(v.begin());
v.emplace(v.begin(), 1, 2, 3);
}
// template class std::vector<X, TaggingAllocator>;
Uncommenting the last line to explicitly instantiate the vector fails differently, presumably there are some SFINAE conditions which make invalid assumptions about the type.
The text was updated successfully, but these errors were encountered: