C++11 trailing return member function using decltype and constness
c++, c++11, constants, decltype, type-deduction
Solution
The problem is that `decltype((i))` return `int&` and apply `const` to that type has no effect. You want something like
template <typename T> struct add_ref_const { typedef T const type; };
template <typename T> struct add_ref_const<T&> { typedef T const& type; };
... and then use
auto acc() const -> typename add_ref_const<decltype((i))>::type { return i; }
That is, the `const` needs to go between the type `T` and the `&`. The solution would have been obvious if you had put the `const` into the correct location: `const` should go to the right.
Problem
I am trying to understand the trailing return based new function declaration syntax in C++11, using decltype. In the following code, I am trying to define a member function returning a const & to allow for read-only access to `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; } ``` As mentioned in the comments, only the last commented version of `acc()` works, whereas using the others, the code just compiles and prints value `1`. Question: How do we have to define the `acc()` function using the new function declaration syntax based on `decltype`, such that the compilation here fails due to returning a `const &int` in `modify_const`, or in other words, such that `acc()` has a proper `const &int` return type. Remark: using `int i;` instead of `int &i;` as the member variable in `X` produces a compile error, as expected. Edited to better distinguish between constness of `v` and `X::i`, respectively. It is the latter I am trying to impose in `acc()`.