Q:

Sorting a vector of unique pointers using constant iterators

My question is about why I can sort a vector of unique pointers with begin/end but not with cbegin/cend
This compiles:
std::sort(teachers.begin(), teachers.end(), compare_by_uniqptr);

But this for some reason gives me a C2280 attempting to reference a deleted function.
std::sort(teachers.cbegin(), teachers.cend(), compare_by_uniqptr);

Here is some context. 'teachers' is a vector of unique pointers of Teacher objects. 
class Teacher : public Person {
private:
  std::vector<std::unique_ptr<Student>> students;
public:
  Teacher(std::string name) : Person(name) {}
  void insert(std::string name);
  int num_students() { return students.size(); }
};

std::vector<std::unique_ptr<Teacher>> teachers;

bool compare_by_uniqptr(const std::unique_ptr<Teacher>& a,
                        const std::unique_ptr<Teacher>& b) 
{
  return a.get()->num_students() > b.get()->num_students();
}

I am sorting them by the amount of students each one has in descending order. The begin/end compiles but cbegin/cend does not. Why?

A:

Unique pointers can not be copied (otherwise they would lose their uniqueness). For that reason when they are sorted, they will need to be moved (or swapped). Those operations need to change the internals of the unique pointers. Of course you can't change the internals of an object through a const reference.

