简体   繁体   English

基于范围的for循环的范围表达式以使用const函数重载

[英]Range expression of range-based for loops to use const function overloads

Update, thanks to AlexD's answer : This question boils down to the language rules for selecting member function overloads, which is discussed in the following question: Calling a const function rather than its non-const version 更新,感谢AlexD的回答 :这个问题归结为选择成员函数重载的语言规则,以下问题对此进行了讨论: 调用const函数而不是其非const版本


When the range expression of a range-based for loop is a call to a member function with const and non- const overloads, it seems that the non- const overload is selected. 基于范围的for循环的范围表达式是对具有const和非const重载的成员函数的调用时,似乎选择了非const重载。 As a result, the following program does not compile: 结果,以下程序无法编译:

#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;
}

Diagnostic message from gcc 5.3: 来自gcc 5.3的诊断消息:

error: 'std::vector<int>& foo::get_numbers()' is protected

But a const version of get_numbers() is available and could be used. 但是可以使用const版本的get_numbers() We can force it to be used by using a const reference to the foo instance, like this: 我们可以通过使用对foo实例的const引用来强制使用它,如下所示:

int main() {
    foo f;
    const foo& g = f;
    for (int x : g.get_numbers()) std::cout << x << std::endl;
}

Is there a better/easier way to tell the compiler that it can and should use the const member function overload, without explicitly making a const reference to the object? 有没有更好/更容易的方法告诉编译器可以并且应该使用const成员函数重载,而无需显式对对象进行const引用?

There are some similar questions about making the range-based for loop use const iterators, but I haven't found any questions about making the loop's range expression const for the purposes of selecting function overloads. 关于使基于范围的for循环使用const迭代器,存在一些类似的问题 ,但是我还没有发现出于选择函数重载的目的而使循环的范围表达式为const任何问题。

But a const version of get_numbers() is available and could be used. 但是可以使用const版本的get_numbers()

The best function is selected before accessibility is considered. 在考虑可访问性之前,已选择最佳功能。 The standard states (emphasis mine): 标准状态(强调我的):

If a best viable function exists and is unique, overload resolution succeeds and produces it as the result. 如果存在最佳可行的功能并且是唯一的,那么过载解析将成功并产生结果。 Otherwise overload resolution fails and the invocation is ill-formed. 否则,重载解析将失败并且调用格式错误。 When overload resolution succeeds, and the best viable function is not accessible (Clause 11) in the context in which it is used, the program is ill-formed. 如果重载解析成功,并且在使用它的上下文中无法访问最佳可行功能 (第11条),则程序格式错误。

A simple template function as_const can make the cast not so ugly. 一个简单的模板函数as_const可以使转换不那么难看。 I believe this is being added or was recently added to the standard library. 我相信这是正在添加或最近添加到标准库。

template <typename T> T const & as_const (T const & t) { return t; }

void f ()
{
    for (auto && x: as_const (y)) {}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM