C++ 使用常量函数重载的基于范围的循环的范围表达式

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

更新,多亏了AlexD的回答:这个问题归结为选择成员函数重载的语言规则,下面的问题将对此进行讨论:


当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.这样更好吗?