Трохи більш багатослівний, ніж Меєрс, але я можу це зробити:
class X {
private:
// This method MUST NOT be called except from boilerplate accessors.
Z &_getZ(size_t index) const {
return something;
}
// boilerplate accessors
public:
Z &getZ(size_t index) { return _getZ(index); }
const Z &getZ(size_t index) const { return _getZ(index); }
};
У приватного методу є небажана властивість: він повертає не-const Z & для екземпляру const, тому він є приватним. Приватні методи можуть порушити інваріанти зовнішнього інтерфейсу (у цьому випадку бажаний інваріант "об'єкт const не може бути змінений за допомогою посилань, отриманих через нього на об'єкти, які він має-a").
Зауважте, що коментарі є частиною шаблону - інтерфейс _getZ вказує, що називати його ніколи не вірно (окрім аксесуарів, очевидно): жодної можливої користі зробити це все одно, тому що це ще 1 символ, який потрібно вводити і не буде в результаті зменшується чи менший код. Виклик методу еквівалентний виклику одного з доступних даних const_cast, і ви цього не хочете робити. Якщо ви переживаєте, щоб зробити очевидні помилки (і це справедлива мета), тоді називайте це const_cast_getZ замість _getZ.
До речі, я ціную рішення Майєрса. У мене немає філософського заперечення проти цього. Однак особисто я віддаю перевагу крихітному контрольованому повторенню та приватному методу, який потрібно викликати лише у певних жорстко контрольованих обставинах, ніж метод, схожий на шум лінії. Виберіть свою отруту і дотримуйтесь її.
[Редагувати: Кевін справедливо зазначив, що _getZ може захотіти викликати подальший метод (скажімо, GeneZ), який спеціально спеціалізується так само, як і getZ. У цьому випадку _getZ побачить const Z & і повинен буде const_cast перед тим, як повернутися. Це все-таки безпечно, оскільки прилад для котлоагрегатів контролює все, але не очевидно, що це безпечно. Крім того, якщо ви зробите це, а потім пізніше зміните generatorZ, щоб завжди повертати const, вам також потрібно змінити getZ, щоб завжди повертати const, але компілятор не скаже вам, що ви робите.
Остання точка щодо компілятора також стосується рекомендованої схеми Майєрса, але перший пункт про неочевидний const_cast не є. Таким чином, я вважаю, що якщо _getZ виявиться потрібним const_cast для його повернення, то ця модель втрачає багато свого значення над Мейєрсом. Оскільки він також зазнає недоліків порівняно з Мейєрсом, я думаю, я перейшов би до його в цій ситуації. Перейменовування з одного на інший є простим - це не впливає на будь-який інший дійсний код у класі, оскільки лише недійсний код та котла викликають _getZ.]