我试图使用decltype理解C ++ 11中基于尾部返回的新函数声明语法。
在下面的代码中,我试图定义一个返回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
中{1}},或换句话说,modify_const
具有正确的acc()
返回类型。
备注:使用const &int
代替int i;
作为int &i;
中的成员变量会产生编译错误,正如所料。
已编辑,以便更好地区分X
和v
的常量。我试图强加于X::i
。
答案 0 :(得分:5)
问题是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
should go to the right。
答案 1 :(得分:0)
修改指向非const的指针的目标的const
成员函数没有任何违法行为,即使该指针是从成员变量中获取的。
从编译器的角度来看,int&
是正确的返回类型。
您的“modify_const
”功能命名不正确。 i
是被修改的内容,而不是const
。
答案 2 :(得分:0)
只需添加&amp;在左侧并跳过尾随返回类型。
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
};
请注意,使用此语法可以在声明函数后声明成员变量。