Let's say we have a simple class that holds a std::string:
class StringWrapper {
public:
const std::string s;
StringWrapper(const std::string s)
: s(s) {}
// We want this to be moveable but not copyable
~StringWrapper() = default;
StringWrapper(const StringWrapper&) = delete;
StringWrapper& operator=(const StringWrapper&) = delete;
StringWrapper(StringWrapper&&) noexcept = default;
StringWrapper& operator=(StringWrapper&&) = default;
};
Here we have tried to make the class moveable, but not copyable. I understand that a const member variable normally prevents a default move ctor from being generated, but here we try to explicitly generate it - and this at least compiles.
Now we try to sort a std::vector<StringWrapper> (the compare function is not important here):
std::vector<StringWrapper> strings;
std::sort(strings.begin(), strings.end(), [](auto const& a, auto const& b) { return true; });
This fails to compile, but the error is very cryptic:
1>...\include\algorithm(7419,25): error C2280: 'StringWrapper &StringWrapper::operator =(const StringWrapper &)': attempting to reference a deleted function
1>...src\example.cpp(476): message : see declaration of 'StringWrapper::operator ='
1>...src\example.cpp(476,24): message : 'StringWrapper &StringWrapper::operator =(const StringWrapper &)': function was explicitly deleted
1>...\include\algorithm(7541): message : see reference to function template instantiation '_BidIt std::_Insertion_sort_unchecked<_RanIt,_Pr>(const _BidIt,const _BidIt,_Pr)' being compiled
1> with
1> [
1> _BidIt=StringWrapper *,
1> _RanIt=StringWrapper *,
1> _Pr=myFunc::<lambda_8668e50965d967f7b587b72f59fcb0cf>
1> ]
1>...\include\algorithm(7571): message : see reference to function template instantiation 'void std::_Sort_unchecked<StringWrapper*,_Fn>(_RanIt,_RanIt,int,_Pr)' being compiled
1> with
1> [
1> _Fn=myFunc::<lambda_8668e50965d967f7b587b72f59fcb0cf>,
1> _RanIt=StringWrapper *,
1> _Pr=myFunc::<lambda_8668e50965d967f7b587b72f59fcb0cf>
1> ]
1>...src\example.cpp(488): message : see reference to function template instantiation 'void std::sort<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>,myFunc::<lambda_8668e50965d967f7b587b72f59fcb0cf>>(const _RanIt,const _RanIt,_Pr)' being compiled
1> with
1> [
1> _Ty=StringWrapper,
1> _RanIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<StringWrapper>>>,
1> _Pr=myFunc::<lambda_8668e50965d967f7b587b72f59fcb0cf>
1> ]
1>...\include\algorithm(7422,28): error C2280: 'StringWrapper &StringWrapper::operator =(const StringWrapper &)': attempting to reference a deleted function
1>...src\example.cpp(476): message : see declaration of 'StringWrapper::operator ='
1>...src\example.cpp(476,24): message : 'StringWrapper &StringWrapper::operator =(const StringWrapper &)': function was explicitly deleted
1>...\include\algorithm(7425,24): error C2280: 'StringWrapper &StringWrapper::operator =(const StringWrapper &)': attempting to reference a deleted function
1>...src\example.cpp(476): message : see declaration of 'StringWrapper::operator ='
1>...src\example.cpp(476,24): message : 'StringWrapper &StringWrapper::operator =(const StringWrapper &)': function was explicitly deleted
Specifically, it suggests that std::sort is trying to reference the deleted copy ctor, but I don't know why that would be the case; I would expect std::sort to use only move operations.
Can anyone explain to me what is going on here?