Просто объявите оба, но убедитесь, что версия const
разрешает только const
доступ:
template <typename T>
struct A {
A(T a) : _value{a} {}
T& value() {return _value;}
const T& value() const {return _value;}
private:
T _value;
};
Рассмотрим варианты использования:
void show(int);
void modify(int&);
void f1(A<int>& a) {
show(a.value());
modify(a.value());
}
Хорошо, a.value()
возвращает int&
здесь, поэтому переменная может быть изменена.
void f2(A<const int>& a) {
show(a.value());
// modify(a.value()); // invalid
}
Здесь, даже если мы вызываем T& value();
, поскольку T
равен const int
, тип возвращаемого значения const int&
, и значение не может быть изменено.
void f3(const A<int>& a) {
show(a.value());
// modify(a.value()); // invalid
}
Теперь мы вызываем const T& value() const
;, поэтому тип возвращаемого значения const int&
. Снова значение не может быть изменено.
void f4(const A<const int>& a) {
show(a.value());
// modify(a.value()); // invalid
}
Этот также называется const T& value() const
. При T=const int
язык «сворачивает» избыточный const
, так что const T
совпадает с const int
, а тип возвращаемого значения - const int&
. Таким образом, значение не может быть изменено.