为什么使用 Iterator 和 Range 的 Fibonacci 系列会抛出错误
Why does the Fibonacci Series using Iterator and Range throw error
我正在练习CPP速成教程(第8章,练习1)中的C++代码片段,Link下面的代码无法编译,下面提供了程序的错误。如果提供任何有助于理解的建议或链接,将会很有帮助。 :).
#include <cstdio>
struct FibonacciIterator {
bool operator!=(int x) const {
return x >= current;
}
FibonacciIterator& operator++() {
const auto tmp = current;
current += last;
last = tmp;
return *this;
}
int operator*() const {
return current;
}
private:
int current{ 1 }, last{ 1 };
};
struct FibonacciRange {
explicit FibonacciRange(int max) : max{ max } { }
FibonacciIterator begin() const {
return FibonacciIterator{};
}
int end() const {
return max;
}
private:
const int max;
};
int main() {
for (const auto i : FibonacciRange{ 50 }) {
printf("%d ", i);
}
}
错误:
user@stretch:/tmp$ g++ test.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:32:46: error: inconsistent begin/end types in range-based ‘for’ statement: ‘FibonacciIterator’ and ‘int’
for (const auto i : FibonacciRange{ 5000 }) {
^
test.cpp:32:46: error: conversion from ‘int’ to non-scalar type ‘FibonacciIterator’ requested
test.cpp:32:46: error: no match for ‘operator!=’ (operand types are ‘FibonacciIterator’ and ‘FibonacciIterator’)
test.cpp:3:10: note: candidate: bool FibonacciIterator::operator!=(int) const
bool operator!=(int x) const {
^~~~~~~~
test.cpp:3:10: note: no known conversion for argument 1 from ‘FibonacciIterator’ to ‘int’
您的 begin
和 end
成员函数 return 不同类型。 Pre-C++17,这些类型需要相同,如错误信息所述
error: inconsistent begin/end types in range-based ‘for’ statement
从 C++17 开始,放宽了对 range-for 循环的限制
As of C++17, the types of the begin_expr
and the end_expr
do not have to be the same, and in fact the type of the end_expr
does not have to be an iterator: it just needs to be able to be compared for inequality with one. This makes it possible to delimit a range by a predicate (e.g. "the iterator points at a null character").
因此,如果您使用 C++17 编译您的代码,通过传递 -std=c++17
标志,您的代码将编译,假设它满足所有其他约束,它确实如此。
我正在练习CPP速成教程(第8章,练习1)中的C++代码片段,Link下面的代码无法编译,下面提供了程序的错误。如果提供任何有助于理解的建议或链接,将会很有帮助。 :).
#include <cstdio>
struct FibonacciIterator {
bool operator!=(int x) const {
return x >= current;
}
FibonacciIterator& operator++() {
const auto tmp = current;
current += last;
last = tmp;
return *this;
}
int operator*() const {
return current;
}
private:
int current{ 1 }, last{ 1 };
};
struct FibonacciRange {
explicit FibonacciRange(int max) : max{ max } { }
FibonacciIterator begin() const {
return FibonacciIterator{};
}
int end() const {
return max;
}
private:
const int max;
};
int main() {
for (const auto i : FibonacciRange{ 50 }) {
printf("%d ", i);
}
}
错误:
user@stretch:/tmp$ g++ test.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:32:46: error: inconsistent begin/end types in range-based ‘for’ statement: ‘FibonacciIterator’ and ‘int’
for (const auto i : FibonacciRange{ 5000 }) {
^
test.cpp:32:46: error: conversion from ‘int’ to non-scalar type ‘FibonacciIterator’ requested
test.cpp:32:46: error: no match for ‘operator!=’ (operand types are ‘FibonacciIterator’ and ‘FibonacciIterator’)
test.cpp:3:10: note: candidate: bool FibonacciIterator::operator!=(int) const
bool operator!=(int x) const {
^~~~~~~~
test.cpp:3:10: note: no known conversion for argument 1 from ‘FibonacciIterator’ to ‘int’
您的 begin
和 end
成员函数 return 不同类型。 Pre-C++17,这些类型需要相同,如错误信息所述
error: inconsistent begin/end types in range-based ‘for’ statement
从 C++17 开始,放宽了对 range-for 循环的限制
As of C++17, the types of the
begin_expr
and theend_expr
do not have to be the same, and in fact the type of theend_expr
does not have to be an iterator: it just needs to be able to be compared for inequality with one. This makes it possible to delimit a range by a predicate (e.g. "the iterator points at a null character").
因此,如果您使用 C++17 编译您的代码,通过传递 -std=c++17
标志,您的代码将编译,假设它满足所有其他约束,它确实如此。