https://llvm.org/bugs/show_bug.cgi?id=28412
Bug ID: 28412 Summary: std::vector incorrectly requires CopyConstructible, Destructible and other concepts Product: libc++ Version: unspecified Hardware: All OS: All Status: NEW Severity: normal Priority: P Component: All Bugs Assignee: unassignedclangb...@nondot.org Reporter: zi...@kayari.org CC: llvm-bugs@lists.llvm.org, mclow.li...@gmail.com Classification: Unclassified 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. -- You are receiving this mail because: You are on the CC list for the bug.
_______________________________________________ llvm-bugs mailing list llvm-bugs@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs