Нет единого «правильного подхода»; это зависит от потребностей вашего приложения.
Если это вообще возможно, вернуть вещи по значению или вернуть копию, с которой звонящий может делать все, что ему захочется.
Вариант вышеупомянутого - вернуть изменяемую копию, а затем предоставить способ атомарного объединения измененного объекта обратно в список. Что-то вроде:
Thing t = myThingList.getThing(key);
t.setFoo(f);
t.setBar(b);
myThingList.merge(t); // ThingList atomically updates the appropriate element
Однако это может вызвать проблемы, если несколько потоков пытаются обновить один и тот же объект.
Идея "объекта в виде указателя" звучит круто, но я подозреваю, что это приведет к трудно обнаруживаемым ошибкам, когда какая-то блокировка не будет снята где-то.
Я бы постарался сохранить весь код блокировки / разблокировки в пределах ThingList
, поэтому функции ThingList::set...
, вероятно, будут такими же, как и я.