C ++의 향상된 FOR 루프
Java에서 C ++로 전환하고 있는데 C ++에 Java에서 사용한 향상된 for 루프가 포함되어 있는지 궁금합니다. 예를 들면 다음과 같습니다.
int[] numbers = {1,2,3,4,5,6,7,8,9,10};
for (int item : numbers) {
System.out.println("Count is: " + item);
}
C ++에서도 동일한 "바로 가기"가 가능합니까?
C ++ 11에서 컴파일러가 지원한다면 그렇습니다. 범위 기반이라고합니다.
std::vector<int> v;
// fill vector
for (const int& i : v) { std::cout << i << "\n"; }
C 스타일 배열 및 함수가 begin()
있고 end()
반복기를 반환 하는 모든 유형에서 작동 합니다. 예:
class test {
int* array;
size_t size;
public:
test(size_t n) : array(new int[n]), size(n)
{
for (int i = 0; i < n; i++) { array[i] = i; }
}
~test() { delete [] array; }
int* begin() { return array; }
int* end() { return array + size; }
};
int main()
{
test T(10);
for (auto& i : T) {
std::cout << i; // prints 0123456789
}
}
C ++ 11은 그렇습니다. 범위 기반 fors라고합니다. 유형을 const에 대한 참조 또는 참조로 한정해야합니다.
C ++ 03에 대한 해결 방법은 BOOST_FOR_EACH 또는 std :: for_each 와 함께 boost :: bind 입니다 . Boost.Lambda를 사용하면 더 멋진 일이 가능합니다. 자신이나 동료를 좌절시킬 기분이 든다면 더 이상 사용되지 않는 바인더 및 .std::bind1st
std::bind2nd
다음은 몇 가지 예제 코드입니다.
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <boost/lambda/lambda.hpp>
#include <functional>
int main()
{
int i = 0;
std::vector<int> v;
std::generate_n(std::back_inserter(v), 10, [&]() {return i++;});
// range-based for
// keep it simple
for(auto a : v)
std::cout << a << " ";
std::cout << std::endl;
// lambda
// i don't like loops
std::for_each(v.begin(), v.end(), [](int x) {
std::cout << x << " ";
});
std::cout << std::endl;
// hardcore
// i know my lib
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
// boost lambda
// this is what google came up with
// using for the placeholder, otherwise this looks weird
using namespace boost::lambda;
std::for_each(v.begin(), v.end(), std::cout << _1 << " ");
std::cout << std::endl;
// fold
// i want to be a haskell programmer
std::accumulate(v.begin(), v.end(), std::ref(std::cout),
[](std::ostream& o, int i) -> std::ostream& { return o << i << " "; });
return 0;
}
C ++ 03에는 그러한 가능성이 없습니다. 그러나 새로운 표준 (C ++ 11)에는 그것을 가지고 있습니다. 예제 참조 ( Wikipedia 에서 가져옴 ) :
int my_array[5] = {1, 2, 3, 4, 5};
for (int &x : my_array) {
x *= 2;
}
std::vector<int>
일반 배열 대신 사용 하는 것도 고려하십시오 . 이것은 C 데이터 유형에 대한 C ++ 비유로 삶을 더 쉽게 만듭니다.
예, 아니오.
1. 로컬 어레이 : 아니요,하지만 쉽게 크기를 찾을 수 있습니다.
로컬 배열 ( int numbers[4] = {1, 2, 3, 4];
)이 있으면 할 수 있습니다 size = sizeof(numbers) / sizeof(int)
.
2. Pointer to array: Not at all, you have to pass the size around separately
If you have a pointer to an array (int* numbers = new int[4];
) then you can't figure out the size unless you keep track of it yourself. (or if it's null terminated in the case of a c string, but then you have to iterate through it which is linear running time...)
Note that I don't believe pointer to array is the proper terminology, really you just have a pointer to the first element of the array but space for multiple values has been allocated. Not sure what this is called. Maybe just a pointer?
3. STL containers: Yes, and you can do some for loop magic using iterators, or just use indices by getting the size
If you have a vector (std::vector<int> v(3, 0);
) then you can iterate through it the following ways:
C++11:
auto it = v.begin();
for (auto it = v.begin(); it != v.end(); it++)
{
UseElement(*it);
}
Or apparently (also C++11, thanks jrok):
for (const int& i : v) { UseElement(i); }
C++ (pre-11):
std::vector<int>::iterator it;
for (it = v.begin(); it != v.end(); it++)
{
UseElement(*it);
}
Or using indices:
for (int i = 0; i < v.size(); i++)
{
UseElement(v[i]);
}
Furthermore, you can use function pointers or functors with STL containers using std algorithm's for_each (#include <algorithm>
) like so:
void foo(int i)
{
std::cout << i;
}
{
std::for_each(myvector.begin(), myvector.end(), foo);
}
Others already mentioned that this loop style was added in C++11. However C++11 is even better:
for (auto const& item: numbers)
{
std::cout << "Count is: " << item << '\n';
}
That way, if you later change the element type of numbers
from int
to long
, or even to some bigint
class you wrote yourself, you don't need to change that for loop at all.
In the old standard, C++03 (which is from 2003), the language has no built-in support for that kind of for-loop. There are some artifices you can use with Boost, but imo it's not worth including a whole new library for this small convenience feature.
In the new standard, C++11 (which was released just last summer), this is possible; the syntax looks like this:
MyType array[] = { ... }
for (MyType& x : array) {
...
}
Note that I'm using MyType& x
, not MyType x
. In Java everything is a reference. In C++ references have to be explicit, and you declare them using &
. If you don't use references, the for-loop will copy each element of the array into x
(which might be expensive to do).
However, C++11 is not fully supported by most compilers yet. I think Microsoft's Visual C++ supports this feature, but I'm not sure.
I find this simple macro very useful. The vast majority of my for
loops involve iterating over an STL container:
#define For(it, container) for( typeof((container).begin()) it = (container).begin(); it != (container).end(); ++it)
An example:
vector<int> vector_of_ints;
... // initialize it somehow
For(integer, vector_of_ints) {
cout << *integer << endl;
}
There are two things to be aware of with this: First, it's an iterator and hence you must dereference it. And second, the second parameter to the For
will be evaluated many times. I have played with other approaches, but I keep returning to the simplicity of this.
ReferenceURL : https://stackoverflow.com/questions/8378583/enhanced-for-loops-in-c
'IT박스' 카테고리의 다른 글
의사 무작위로 선택된 IP 주소에 대한 핑을 사용하여 진정한 난수를 생성 할 수 있습니까? (0) | 2021.01.05 |
---|---|
C #에서 파일의 마지막 수정 날짜 확인 (0) | 2021.01.05 |
Silverlight 개발자 런타임을 설치할 수 없습니다. (0) | 2021.01.05 |
Maven 설치 목표에서 테스트를 건너 뛰고 Maven 테스트 목표에서 실행하는 방법은 무엇입니까? (0) | 2021.01.05 |
부트 스트랩 3에서 글 리피 콘을 제대로 표시 할 수 없음 (0) | 2021.01.05 |