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()
.
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 .
There's nothing illegal about a const
member function modifying the target of a pointer to non-const, even if that pointer was gotten from a member variable.
From the compiler's perspective, int&
IS the correct return type.
Your " modify_const
" function is incorrectly named. i
is what gets modified, and is not const
.
Simply add an & to the left and skip the trailing return type.
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
};
Note that using this syntax you can declare the member variable after you have declared the function.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.