Пункт 3 в книге Скотта Мейерса Эффективный C ++ демонстрирует метод удаления этого дублирования кода. По сути, в вашей неконстантной функции вы добавите const к this
, вызовите версию const, а затем отбросите const. Это безопасно; хотя запись в const-переменную приводит к неопределенному поведению, потому что this
изначально был неконстантным, все в порядке.
Пример:
const std::string& operator[](size_t index) const
{
// some other code
// since `this` isn't really const, this is modifiable
return mData[index];
}
std::string& operator[](size_t index)
{
return const_cast<std::string&> // (3) take const off result
(static_cast<const my_type&> // (1) add const
(*this)[index]); // (2) use const version
}
Обычно все это будет в одной строке. Вы также можете сделать утилиту для него.
Обратите внимание на предостережение: если константная версия возвращает «реальный» константный объект, этот метод явно приводит к неопределенному поведению. Константность возвращаемого значения должна быть отражена константой объекта, на который указывает this
. Это неработающий код:
const std::string& operator[](size_t index) const
{
static const std::string constString = "Don't modify me.";
if (index == 0)
{
// even though `this` isn't really const, this is NOT modifiable
return constString;
}
return mData[index - 1];
}
std::string& operator[](size_t index)
{
return const_cast<std::string&> // (3) !!! take const off result !!!
(static_cast<const my_type&> // (1)
(*this)[index]); // (2)
}
На практике мы избегаем глобального состояния, поэтому это редко является проблемой. В любом случае, это тривиально проверить.