[英]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 ofget_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.