Завершающая возвращаемая функция-член C ++ 11 с использованием decltype и constness

Я пытаюсь понять синтаксис объявления новой функции на основе конечного возврата в C ++ 11, используя decltype.

В следующем коде я пытаюсь определить функцию-член, возвращающую const & чтобы разрешить доступ только для чтения в i

#include <iostream>
#include <type_traits>

struct X {
int &i;

X(int &ii) : i(ii) {}

//    auto acc() const -> std::add_const<decltype((i))>::type { return i; } // fails the constness test
auto acc() const -> decltype(i) { return i; } // fails the constness test
//    const int &acc() const { return i; } // works as expected
};

void modify_const(const X &v) {
v.acc() = 1;
}

int main() {
int i = 0;
X x(i);

modify_const(x);
std::cout << i << std::endl;

return 0;
}

Как уже упоминалось в комментариях, только последняя закомментированная версия acc() работает, тогда как при использовании других код просто компилирует и печатает значение 1,

Вопрос: Как мы должны определить acc() функция с использованием нового синтаксиса объявления функции на основе decltype, такой, что компиляция здесь не удается из-за возврата const &int в modify_constили, другими словами, такой, что acc() имеет надлежащий const &int тип возврата.

замечание: с помощью int i; вместо int &i; в качестве переменной-члена в X выдает ошибку компиляции, как и ожидалось.

отредактированный чтобы лучше различать постоянство v а также X::iсоответственно. Это последнее, что я пытаюсь навязать в acc(),

4

Решение

Проблема в том, что decltype((i)) вернуть int& и применить const на этот тип не влияет. Вы хотите что-то вроде

template <typename T> struct add_ref_const { typedef T const type; };
template <typename T> struct add_ref_const<T&> { typedef T const& type; };

… а затем использовать

auto acc() const -> typename add_ref_const<decltype((i))>::type { return i; }

Это const должен идти между типом T и &, Решение было бы очевидным, если бы вы поставили const в правильное место: const должен идти направо.

4

Другие решения

В этом нет ничего противозаконного const функция-член, изменяющая цель указателя на неконстантную, даже если этот указатель был получен из переменной-члена.

С точки зрения компилятора, int& Это правильный тип возврата.

Ваш «modify_constmsgstr «функция неверно названа. i это то, что модифицируется, а не const,

0

Просто добавьте & налево и пропустите завершающий тип возврата.

struct X {
int &i;

X(int &ii) : i(ii) {}

auto& acc() const { return i; } // Returns const reference
auto& acc() { return i; } // Returns non-const reference
const auto& acc() const { return i; } // Add const to the left to make it even more readable
};

Обратите внимание, что используя этот синтаксис, вы можете объявить переменную-член после того, как объявили функцию.

0
По вопросам рекламы [email protected]