Um pouco mais detalhado do que Meyers, mas eu posso fazer isso:
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); }
};
O método private tem a propriedade indesejável de retornar um Z não-const e para uma instância const, e é por isso que é privado. Métodos privados podem quebrar invariantes da interface externa (neste caso, a invariável desejada é "um objeto const não pode ser modificado através de referências obtidas através dele para objetos que possui-a").
Observe que os comentários fazem parte do padrão - a interface de _getZ especifica que nunca é válido chamá-lo (além dos acessadores, obviamente): não há benefício concebível em fazê-lo, porque é mais um caractere a ser digitado e não será resultar em código menor ou mais rápido. Chamar o método é equivalente a chamar um dos acessadores com um const_cast, e você também não deseja fazer isso. Se você está preocupado em tornar os erros óbvios (e esse é um objetivo justo), chame-o de const_cast_getZ em vez de _getZ.
A propósito, eu aprecio a solução de Meyers. Não tenho objeções filosóficas a isso. Pessoalmente, porém, prefiro um pouco de repetição controlada e um método privado que só deve ser chamado em determinadas circunstâncias bem controladas, em vez de um método que se parece com ruído de linha. Escolha o seu veneno e fique com ele.
[Editar: Kevin apontou, com razão, que _getZ pode querer chamar outro método (digamos generateZ), que é constantemente especializado da mesma maneira que getZ. Nesse caso, _getZ verá uma const Z & e terá que const_cast antes de retornar. Isso ainda é seguro, pois o acessador do clichê monitora tudo, mas não é extremamente óbvio que é seguro. Além disso, se você fizer isso e depois alterar o generateZ para sempre retornar const, também será necessário alterar getZ para sempre retornar const, mas o compilador não informará o que você faz.
Esse último ponto sobre o compilador também se aplica ao padrão recomendado por Meyers, mas o primeiro ponto sobre um const_cast não óbvio não é. Portanto, pensando bem, se _getZ precisar de um const_cast para seu valor de retorno, esse padrão perderá muito do seu valor sobre o de Meyers. Como também sofre desvantagens em comparação com as de Meyers, acho que mudaria para a dele nessa situação. A refatoração de um para o outro é fácil - não afeta nenhum outro código válido na classe, pois apenas o código inválido e o clichê chamam _getZ.]