C++ 使用常量函数重载的基于范围的循环的范围表达式
更新,多亏了AlexD的回答:这个问题归结为选择成员函数重载的语言规则,下面的问题将对此进行讨论:C++ 使用常量函数重载的基于范围的循环的范围表达式,c++,c++11,for-loop,foreach,C++,C++11,For Loop,Foreach,更新,多亏了AlexD的回答:这个问题归结为选择成员函数重载的语言规则,下面的问题将对此进行讨论: 当a的范围表达式是对具有const和非const重载的成员函数的调用时,似乎选择了非const重载。因此,以下程序无法编译: #include <iostream> #include <vector> class foo { public: const std::vector<int>& get_numbers() const
当a的范围表达式是对具有
const
和非const
重载的成员函数的调用时,似乎选择了非const
重载。因此,以下程序无法编译:
#include <iostream>
#include <vector>
class foo {
public:
const std::vector<int>& get_numbers() const { return numbers; }
protected:
std::vector<int>& get_numbers() { return numbers; }
private:
std::vector<int> numbers;
};
int main() {
foo f;
for (int x : f.get_numbers()) std::cout << x << std::endl;
}
有没有更好/更简单的方法告诉编译器,它可以并且应该使用const
成员函数重载,而不显式引用对象
有一些关于使用const
迭代器使循环使用基于范围的方法,但是我没有发现任何关于使循环的范围表达式const
用于选择函数重载的问题
但是可以使用get_numbers()
的const
版本
在考虑可访问性之前,选择最佳功能。该标准规定(重点是矿山):
如果存在一个最佳可行函数且该函数是唯一的,则重载解析将成功并产生结果。
否则重载解析将失败,并且调用的格式不正确重载解析成功时,以及
最佳可行功能不可访问(第11条)。在使用该功能的上下文中,程序是
格式不正确
但是可以使用get_numbers()
的const
版本
在考虑可访问性之前,选择最佳功能。该标准规定(重点是矿山):
如果存在一个最佳可行函数且该函数是唯一的,则重载解析将成功并产生结果。
否则重载解析将失败,并且调用的格式不正确重载解析成功时,以及
最佳可行功能不可访问(第11条)。在使用该功能的上下文中,程序是
格式不正确
一个简单的模板函数
as_const
可以使演员阵容不那么难看。我相信这是正在添加或最近添加到标准库中的
template <typename T> T const & as_const (T const & t) { return t; }
void f ()
{
for (auto && x: as_const (y)) {}
}
template T const&as_const(T const&T){return T;}
空f()
{
对于(auto&&x:as_const(y)){
}
一个简单的模板函数作为常量
可以使演员阵容不那么难看。我相信这是正在添加或最近添加到标准库中的
template <typename T> T const & as_const (T const & t) { return t; }
void f ()
{
for (auto && x: as_const (y)) {}
}
template T const&as_const(T const&T){return T;}
空f()
{
对于(auto&&x:as_const(y)){
}
我认为这是因为f
声明为foo-f代码>和非常量foo f代码>这就是为什么选择非常量重载函数而不是常量。我的问题是为什么您需要公共和私有的getNumbers()
?避免任何私有/受保护的getter/setter(或使用其他名称)@DimChtz是的,这就是问题所在。选择的重载是函数签名,而不是返回类型。@DieterLücking Yes。。。这是一个人为的例子,完全是为了说明这个问题。这个问题与正确使用getter无关,但感谢您的输入。将getter设置为私有不是违背getter的目的吗…?我相信这是因为f
声明为foo f代码>和非常量foo f代码>这就是为什么选择非常量重载函数而不是常量。我的问题是为什么您需要公共和私有的getNumbers()
?避免任何私有/受保护的getter/setter(或使用其他名称)@DimChtz是的,这就是问题所在。选择的重载是函数签名,而不是返回类型。@DieterLücking Yes。。。这是一个人为的例子,完全是为了说明这个问题。这个问题与正确使用getter无关,但感谢您的输入。将getter设置为私有不是有损于getter的用途吗?谢谢,这是一个很好的信息,有助于理解为什么选择了non-const
重载。但它并不能完全回答这样一个问题:是否有更方便的方法来选择const
重载,而无需显式引用实例。@TypeIA其他一些人的建议与您的建议相同:谢谢,这是一个很好的链接,我已将其添加到问题的顶部。这个链接问题实际上是这个问题的核心,它与基于范围的for循环无关。谢谢,这是一个很好的信息,可以理解为什么选择了非const
重载。但它并不能完全回答这样一个问题:是否有更方便的方法来选择const
重载,而无需显式引用实例。@TypeIA其他一些人的建议与您的建议相同:谢谢,这是一个很好的链接,我已将其添加到问题的顶部。这个链接的问题实际上是这个问题的核心,它与基于范围的for循环无关。将模板void添加为_const(const T&&)=delete会更安全代码>以防止对临时变量的挂起引用。很好,我不知道您可以删除任意函数声明\u t
是保留的。使用其他工具。@T.C.这样更好吗?C++17。将模板void添加为_const(const T&&)=delete会更安全代码>以防止对临时变量的挂起引用。很好,我不知道您可以删除任意函数声明\u t
是保留的。用别的东西。@T.C.这样更好吗?